题目描述
输入一个链表,输出该链表中倒数第k个结点。
与LeetCode上删除倒数第k个节点类似,两次遍历的方法很简单,这里看一次遍历的方法。
设置两个指针p1,p2(开始都初始化为头节点),p1走到第k个节点后,两个指针一起向右走,当p1走到尾节点时,p1指向的节点即为倒数第k个节点。
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
ListNode* p1 = pListHead, *p2 = pListHead;
int count = 0;
if(pListHead == NULL || k == 0) return NULL;
while(count < k)
{
if(p1 != NULL)
count++;
else
{
return NULL;
}
p1 = p1->next;
}
if(p1 == NULL) return pListHead;
p2 = p2->next;
while(p1->next != NULL)
{
p1 = p1->next;
p2 = p2->next;
}
return p2;
}
};
需要注意的情况:
(1)链表头节点指针为空,返回NULL;
(2)k为0,返回NULL;
(3)链表节点数小于k,返回NULL。(p1右移到第k个节点的过程判断是不是指向NULL,是的话直接返回了。由于最后一次循环,p1指向了第k+1个节点,所以下面加了if判断。另外,为了让两个指针保持距离k-1,p2先往右走了一步,两个指针再一起走,下面的循环结束条件是p1到达尾节点,也即p1->next为NULL,这时p2指向倒数第k个节点。)
书上更清晰的写法:
p1走k-1步,每次看要走过去的下一个节点是否为空,这样最后p1刚好走到第k个节点,且第k个节点不为空。
(while条件有时候判断当前操作节点,有时候判断当前节点的下一个节点)