剑指offer14_链表中倒数第k个结点_题解

链表中倒数第k个结点

题目描述

输入一个链表,输出该链表中倒数第k个结点。

分析

方案一:快慢指针

使用快慢指针,首先让快指针先行k步,然后让快慢指针每次同行一步,直到快指针指向空节点,慢指针就是倒数第K个节点。

参考链接:

牛客官方题解

力扣题解

/**
时间复杂度:O(n)
空间复杂度:O(1)
**/
class Solution {
public:
    // 快慢指针
    ListNode *FindKthToTail(ListNode *pListHead, unsigned int k)
    {
        // 特判头结点为空和k<=0的情况
        if (!pListHead || k <= 0)
            return NULL;
        ListNode *p = pListHead, *q = p;
        //快指针q先行k步
        while (k--)
        {
            if (q != NULL)
                q = q->next;
            else
                return NULL;
        }
        // 快慢指针同行直到快指针q指向空节点
        while (q != NULL)
        {
            p = p->next;
            q = q->next;
        }
        // 返回慢指针即倒数第k个节点
        return p;
    }
};

方案二:求链表倒数第 \(k\) 个节点转换为求正数第 \(n-k\) 个节点

假设有\(5\) 个节点,序号 \(1\) 表示第 \(1\) 个节点,假设求倒数第 \(k\) 个,那么正数就应该是从头结点开始往后推\((n-k)\) 个,\(n\) 代表所有节点的个数(不包含空节点),也可以说 \(n\) 代表指针的个数

下图中 \(n=5,k=2\),所以需要从头结点往后经过 \(n-k=5-2=3\) 个指针

图片说明

/**
时间复杂度:O(n)
空间复杂度:O(1)
**/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        // 特判头结点为空和k<=0的情况
        if(!pListHead || k <= 0) return NULL;
        int len = 0;
        ListNode* p = pListHead;
        //计算链表长度len
        while(p != NULL){
           p = p->next;
           ++len;
        }
        // 特判k>len的情况
        if(len < k) return NULL;
        len -= k;//求链表倒数第k个节点转换为求正数第n-k个节点
        // 从头结点往后数n-k个节点
        while(len--){
            pListHead = pListHead->next;
        }
        return pListHead;
    }
};
posted @ 2020-12-12 16:57  RiverCold  阅读(58)  评论(0编辑  收藏  举报