《从头再来》剑指offer.22 链表中倒数第k个节点

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

 

最简单的方法:前后双指针。前指针先向前走k步,然后前指针不为空的时候,前后指针一起移动,直到前指针为nullptr时,返回后指针,后指针的位置就是倒数第k个节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode *front = head;
        ListNode *rear = head;

        //前指针向前移动k步
        for(int i = 0; i < k; ++i){
            front = front->next;
        }//此处for循环可以优化,使用while(k--),移动
        //前后指针一起移动
        while(front != nullptr){
            front = front->next;
            rear = rear->next;
        }
        return rear;
    }
};

第二种方法:借助栈来解决。当头节点不为空的时候,将所有结点压入栈,然后弹栈k-1个元素,此时栈顶元素就是我们想要的结点,直接返回栈顶元素即可。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        //栈,先压栈,再弹k-1个栈,然后返回栈顶元素(链表的东西,多画图)
        stack<ListNode*>    stk;
        while(head != nullptr){
            stk.push(head);
            head = head->next;
        } 
        while(--k)  stk.pop();
        return stk.top();
    }
};

 

这里又提到了双指针,那么就将双指针和链表的相爱相杀说一下吧。

链表是一个很难得到长度和具体位置的东西,相对于数组的顺序存储来说,获取链表的长度和某个节点的具体位置时很难办到的。但是面试中又一定会问到关于长度和位置的问题,那我们就借用双指针来解决一下吧。

常见问题1、链表中的倒数第k个节点。

解法就是上面所提到的前后双指针,先前指针移动k位,然后前后指针一起移动,直到前指针指向nullptr,返回后指针的位置即为倒数第k个节点。

常见问题2、如何取得链表的中点?

这个问题要分两种情况,需要看节点的个数是奇数还是偶数。但不管奇数还是偶数个节点个数,都是使用快慢指针。快慢指针的意思是说,如果没有到链表的尾部,快指针每次都移动两步,慢指针每次移动一步直到快指针不能移动两步的时候,慢指针指向的位置就是链表的中点(奇数个节点)/中点靠前的节点(偶数个节点)。但是如果是偶数个节点如何取到靠后的节点呢?只需要同时限制快指针的next也不为nullptr即可。

常见问题3、如何判断链表是否有环?

同样的快慢双指针,每次快指针移动两步,慢指针移动一步,如果快慢指针相遇了(fast == slow),则证明有环。

常见问题4、问题3的基础上,如何判断环的长度?

继续移动双指针,直到第二次相遇,两次相遇之间移动的次数就是环的长度。

常见问题5、问题3的基础上,如何找到环的开头?

快慢指针相遇以后,将快指针移动到链表的开头,然后和慢指针一样一次移动一步,相遇的地方就是环的开头。

《从头再来》

posted @ 2021-06-03 19:59  丶原来是枝知啊i  阅读(62)  评论(0)    收藏  举报