刷题:牛客JZ22 链表中倒数最后k个结点

123 阅读1分钟

网址: www.nowcoder.com/practice/88…

描述

输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。
如果该链表长度小于k,请返回一个长度为 0 的链表。

数据范围:0 \leq n \leq 10^50≤n≤105,0 \leq a_i \leq 10^90≤ai​≤109,0 \leq k \leq 10^90≤k≤109
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

例如输入{1,2,3,4,5},2时,对应的链表结构如下图所示: image.png 其中蓝色部分为该链表的最后2个结点,所以返回倒数第2个结点(也即结点值为4的结点)即可,系统会打印后面所有的节点来比较。

 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
        ListNode* FindKthToTail(ListNode* pHead, int k) {
        if(pHead==nullptr || k==0)   //特殊情况
        {
            return nullptr;
        }
        int count=0;
        ListNode* ans=pHead;   //先让ans指针指向头指针
        while(pHead)
        {
            count++;
            if(count<k)   //先让pHead指针走到第k个结点
            {
                pHead=pHead->next;
            }
            else {
                if(pHead->next)   
                //然后两个指针同时移动,以pHead指针指向的结点为终点,ans指针始终指向倒数第k个结点
                {
                    pHead=pHead->next;
                    ans=ans->next;
                }
                else return ans;
            }
        }
        return nullptr;   //k大于结点个数的情况
    }
};

总结:

用双指针,ans指针指向头指针,另一个指针pHead走完k个结点,此时两个指针相差k个结点。然后ans指针和pHead指针同时往后走,当pHead走完时,ans指针就指向了倒数第k个结点。