笔者由于在找工作,所以近期最主要的任务就是准备面试,不打无准备之仗。只有你准备充分了,那么你想要的机会才有机会入你怀中。
笔者会将准备面试的学习过程记录下来,方便自己复盘的同时也希望能给一道找工作的小伙伴们一些帮助。笔者准备的内容大纲如下
下面是本篇博客的正菜部分:
倒数第K个节点
在一个单链表中找到倒数第k个节点
很容易想到先遍历一次链表节点个数n,第二次遍历只需要找第n-k+1个节点。
当你说出这个想法的时候,面试官肯定会提示你他期待的答案是只允许遍历一次链表
关键点:是否可以想到使用两个指针,移动过程中两个所在位置始终相差k-1的距离。当前一个指针移到尾部时,后一个指针正好指向倒数第k个结点。
public ListNode findKthTail(ListNode pHead, int k){
if(pHead == null || k<=0) return null;
ListNode pAHead = pHead;
ListNode pBehind = null;
//使前面的指针快与后面的节点k-1个节点位
for(int i=0;i<k-1;i++){
if(pAHead.next != null){ //容易忽视隐藏的边界条件,有可能k的值大于节点数
pAHead = pAHead.next;
}else{
return null;
}
}
//让两个指针始终保持k-1个节点位,等前面的节点到尾节点时,后一个节点到达倒数第k个节点
pBehind = pHead;
while(pAHead.next != null){
pAHead = pAHead.next;
pBehind = pBehind.next;
}
return pBehind;
}
引申:如果让一次遍历找链表的中间结点可以使用类似的方法。只需要在指针移动时,前一个指针一次移动两个节点,后一个指针一次移动一个节点。前一个指针到达尾部时,后一个指针到达中间节点。
反转链表
反转一个单链表,返回它的头节点。
很容易想到的是直接反转,后一个节点指向前一个节点。但是会有一个问题,到为尾节点的时候,会发生链表中断,这是因为尾节点的下一个结点为空。
关键点:要将前一个节点保存下来,所以要使用三个指针
public ListNode reverseListNode(ListNode pHead){
if(pHead ==null) return null;
ListNode pNewHead = null;
ListNode pPre = null;
ListNode pCur = pHead;
while(pCur !=null){
ListNode pNext = pCur.next;
if(pNext == null){ //找到新的头节点
pNewHead = pCur;
}
pCur.next = pPre; //反转
pPre = pCur;
pCur = pNext;
}
return pNewHead;
}
是否可以想到添加一个指针来保存之前的节点是解题的关键