输入一个链表,输出该链表中倒数第k个结点。
思路有下面几种:
1. 先反转链表,再从前向后找到第k个,
2. 两个指针,一个先走K步,另一个指针从头开始,两个指针一起走,先走的指针到达末尾时,前面的指针就是倒数第k个节点
3. 遍历一次,使用vector顺序保存所有节点,vector.size() - k 即为倒数第k个节点
代码如下:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
//方法一:反转链表 再正向找第k个节点
//方法二:两个指针 一个先走K步,然后两个指针一起走,先走的指针到达末尾时,前面的指针就是倒数第k个节点
ListNode* find_knode_2pointer(ListNode* pListHead, unsigned int k){
ListNode* lnode = pListHead;
ListNode* rnode = pListHead;
for(int i = 1; i <= k; i++){
if(NULL == rnode){
return NULL;
}
else{
rnode = rnode->next;
}
}
while(rnode){
lnode = lnode->next;
rnode = rnode->next;
}
return lnode;
}
//方法三:其实是对方法二的另一种实现方式
ListNode* find_knode_2pointer2(ListNode* pListHead, unsigned int k){
ListNode* lnode = pListHead;
ListNode* rnode = pListHead;
int index = 0;
for(; rnode;){
if(index < k){
rnode = rnode->next;
index++;
}
else{
lnode = lnode->next;
rnode = rnode->next;
}
}
return index < k ? NULL : lnode;
}
//方法四:遍历一次 将所有节点放入vector 则可直接返回vector的temp.size()-k个元素
ListNode* find_knode_by_vector(ListNode* pListHead, unsigned int k){
vector<ListNode*> temp;
ListNode* node = pListHead;
while(node){
temp.push_back(node);
node = node->next;
}
if(temp.size() < k){
return NULL;
}
else{
return temp[temp.size()-k];
}
}
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
//return find_knode_2pointer(pListHead, k);
return find_knode_2pointer2(pListHead, k);
//return find_knode_by_vector(pListHead, k);
}
};