题目:输入一个链表,输出该链表中倒数第k个结点。
遍历两次链表,代码如下:
class Solution{
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){
if (pListHead == NULL || k == 0){
return NULL;
}
int size = 0;
ListNode* pos = pListHead;
while (pos){
++size;
pos = pos->next;
}
//不加k>size的判断就会报错,因为(size-k+1)<0时(size-k+1)的运算结果会转换成unsigned int,接近正无穷大。
//您的代码已保存
//段错误:您的程序发生段错误,可能是数组越界,堆栈溢出(比如,递归调用层数太多)等情况引起
//case通过率为0.00%
if (k > size){
return NULL;
}
for (int i = 1; i < (size-k+1); ++i){
pListHead = pListHead->next;
}
return pListHead;
}
};
一般面试中用最蠢的方法面试官肯定是不满意的,那么有没有一次遍历方法呢?答案是肯定的!
遍历一次链表代码思路如下:两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指针走(k-1)步,到达第k个节点。然后两个指针同时往后移动,当第一个指针到达末尾的时候,第二个指针所在位置就是倒数第k个节点了。
代码如下:
class Solution{
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){
if (pListHead == NULL || k == 0){
return NULL;
}
ListNode* pre = pListHead;
ListNode* last = pListHead;
for (int i = 1; i < k; ++i){
if (pre->next){
pre = pre->next;
}
else{
return NULL;
}
}
while (pre){
pre = pre->next;
if (pre){
last = last->next;
}
}
return last;
}
};