有关剑指offer题目的解析:剑指offer 题目整理
题目要求
输入一个链表,输出该链表中倒数第k个结点。
解题分析
我们可以用两次遍历解决问题,第一次遍历是统计链表中的节点个数,第二次找到倒数第k个点。但是这样需要我们两次遍历链表,通常情况下,面试官需要我们一次遍历解决问题,所以有没有更好的方法?
这时候我们需要两个指针同时完成任务,第一个指针从头遍历k-1步同时第二个指针不动,从第k步开始,两个指针同时遍历,直到第一个指针到达尾部,第二个指针刚好在倒数第k个节点。
注意!!!!!
坑点:链表长度是否大于k?k是一个无符号整数,如果k=0 k-1不是-1(做处理防止内存溢出,陷入多层循环导致程序崩溃)。
主要代码c++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==nullptr || k==0)//输入不合法
return nullptr;
ListNode* pFirst = pListHead;
ListNode* pSecond = nullptr;
for(int i=0; i<k-1; ++i)
{
if(pFirst->next!=nullptr) // 防止链表长度小于k
pFirst = pFirst->next;
else
return nullptr;
}
pSecond = pListHead; // 第k步进行
while(pFirst->next != nullptr)
{
pFirst = pFirst->next;
pSecond = pSecond->next;
}
return pSecond;
}
};
总结
本题通过两个指针的配合,能准确求出答案,但是本题需要我们注意的重点是需要判断输入的链表是不是有多余k个节点?以及k=0时候怎么办? 健壮性分析也是我们代码能力的一种体现,经常做一些参数的防御性测试,有助于我们理解函数和代码实现的整体流程。
相似题目
解答:leetcode141 Linked List Cycle(判断链表是否有环)
解答:leetcode876. Middle of the Linked List(寻找链表的中间元素)