题目描述
输入一个链表,输出该链表中倒数第k个结点
为了能够只遍历一次就能找到倒数第k个节点,可以定义两个指针:
(1)第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;
(2)从第k步开始,第二个指针也开始从链表的头指针开始遍历;
(3)由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。
下图展示了在有6个结点的链表上找倒数第3个结点的过程:
注意三处鲁棒性问题:
(1)输入的head为空指针。由于代码会试图访问空指针指向的内存,程序崩溃。
解决:在处理前增加判断空指针的代码
(2)输入的以head为头结点的链表的结点总数少于k。由于在for循环中会在链表上向前走k-1步,仍然会由于空指针造成程序崩溃。
解决:在for循环中增加判断下一个节点是否是空指针的代码
(3)输入的参数k为0。由于k是一个无符号整数,那么在for循环中k-1得到的将不是-1,而是4294967295(无符号的0xFFFFFFFF)。因此for循环执行的次数远远超出我们的预计,同样也会造成程序崩溃。
解决:同(1),在处理前的判断中也判断参数k是否为0。
/*
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 == NULL || k==0)
return NULL;
ListNode *pAhead = pListHead;
ListNode *pBehind = NULL;
for(unsigned int i=0;i<k-1;++i)
{
if(pAhead->next != NULL)
pAhead = pAhead->next;
else
{
return NULL;
}
}
pBehind = pListHead;
while(pAhead->next != NULL)
{
pAhead = pAhead->next;
pBehind = pBehind->next;
}
return pBehind;
}
};