题目:输入一个链表,输出链表中倒数第k个节点,为了符合大多数人的习惯,本题从1开始计数,即链表的尾巴节点是倒数第一个节点。
方法1:先遍历链表得到链表的个数n,倒数第k个节点就是n-k+1再遍历一次链表,找到第n-k+1个节点就是倒数第k个节点;这种方法遍历两次链表;
方法2:先遍历链表把链表压入一个栈,再出栈,第k次出栈就是第k个节点;
方法3:先反转链表,再遍历
方法1:先遍历链表得到链表的个数n,倒数第k个节点就是n-k+1再遍历一次链表,找到第n-k+1个节点就是倒数第k个节点;这种方法遍历两次链表;
方法2:先遍历链表把链表压入一个栈,再出栈,第k次出栈就是第k个节点;
方法3:先反转链表,再遍历
方法4:定义两个指针,第一个指针从链表的头指针开始遍历向前走k-1;第二个指针保持不动,从第k步开始,第二个指针也开始遍历,两个指针差距k-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) {
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;
}
};
相似题目:
- 求链表的中间结点:定义两个指针,同时从链表的头结点出发,一个指针一次走一步,一个指针一个走两步,当走的快的指针走到链表的末尾时,走的慢的指针正好在链表的中间
- 判断一个单项链表是否形成环形结构:像前一个问题一样,如果走的快的指针追上了走的慢的指针,那么链表就是环形链表;如果走的快的指针走到了链表的末尾(next指向NULL)都没有追上第一个指针,那么链表就不是环形结构。
举一反三:当我们用一个指针遍历链表不能解决问题的时候,可以尝试用两个指针遍历链表,可以让其中一个指针遍历的速度快一点,或者让它先走若干步。