剑指offer-15:单链表中倒数第k个结点

来源:互联网 发布:易经软件 知乎 编辑:程序博客网 时间:2024/06/07 10:49

输入一个单链表,输出该链表中的倒数第k个结点。链表的尾结点是倒数第1个结点。

分析

  • 最简单的思路是遍历链表,得到长度n,则倒数第k个结点就是从头结点开始的第(n-k+1)个结点。从头结点开始走n-k+1步即可找到。
  • 上述解法需要遍历链表2次。其实遍历1次也可以。这种题目的套路是设置两个指针。一个指针较快,一个指针较慢。快慢可以有2方面:一是出发的快慢,一个移动的快慢。
  • 本题属于两个指针出发的快慢不同。可以想到两个指针的最终位置为一个在尾结点倒数第1上,一个在倒数第k上。两者相聚k-1。则我们让快指针先走k-1步,然后俩指针同时走,则走到最后这个差距就把k-1卡出来了。

注意

  • 输入指针判空,k判0不要忘
  • 若指针结点少于k个,走到最后空指针。判断当前是否为空。

程序:

// 链表结点定义struct ListNode {    int value;    ListNode * pNext;};// 找到链表的倒数第k个结点,并返回指针ListNode * FindKthFromTail(ListNode * pHead, int k){    // 指针判空,数字判0    if(pHead == nullptr || k == 0)        return nullptr;    // 设置快慢指针    ListNode * pAhead = pHead;    ListNode * pBehind = nullptr;    // 快指针移动k-1步    for(int i = 0; i<k-1; ++i)    {        // 为防止结点小于k,步步加判断        if(pAhead->pNext != nullptr)            pAhead = pAhead ->pNext;        else            return nullptr;    }    // 两指针开始同时移动    pBehind = pHead;    // 快指针一直移动到尾结点    while(pAhead->pNext != nullptr)    {        pAhead = pAhead->pNext;        pBehind = pBehind ->pNext;    }    // 返回慢指针,即为倒数第k个结点    return pBehind;}
原创粉丝点击