题目描述
输入一个链表,输出该链表中倒数第k个结点。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32M,其他语言64M
解题思路
此题,开始就想到引入一个栈,对链表遍历,并且一次压入栈,之后再从栈中弹出k个节点,即为所求。但是这样虽然只遍历了一遍链表,但是引入栈带来了额外的空间消耗,并不是最佳算法。
那么,换个思路,求倒数第k个节点,但是链表只能从头至尾遍历。所以,如果我们能够知道链表的长度length,我们就可以直接从头向后遍历至第length-k+1个节点即可。
此方法,两个循环,每个循环时间复杂度都是o(n);
再进一步分析,能不能只遍历链表一次?
如果想只遍历一次,那么就需要遍历至指针指向第length-k+1个节点,但length不知,就需要考虑一种能替换length的方法。这里就想到,用一个指针1从头至尾遍历,也就相当于length,再来一个指针2在指针1遍历到第k个节点时,再跟着一起遍历即可。
源代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
ListNode* fir = NULL;
ListNode* las = NULL;
fir = pListHead;
las = pListHead;
//记录k值
int a=k;
//记录节点的个数
int count=0;
//fir指针先遍历,并且记录节点数;
//当fir指针遍历至第k个节点时,las指针开始跟着进行遍历,
//这样,当fir指针遍历完时,las所指的就是倒数第k个节点
while(fir!=NULL){
fir = fir -> next;
count++;
if(a<1){
las = las->next;
}
a--;
}
if(count<k) return NULL;
return las;
}
};