题目描述:输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:给定一个链表: 1->2->3->4->5, 和 k = 2. 返回链表 4->5.
方法一:顺序遍历(遍历两次)
思路与算法:最简单直接的方法即为顺序查找,假设当前链表的长度为 count,则我们知道链表的倒数第 k 个节点即为正数第 count−k 个节点,此时我们只需要顺序遍历到链表的第 count - k 个节点即为倒数第 k 个节点。
1、先遍历一遍链表,每遍历一个节点,计数器 +1,遍历整个链表得到链表长度 count
2、倒数第 k 个节点就是顺序遍历的第 count - k + 1 个节点
3、再次遍历链表,找到第 count - k + 1 个节点,返回该节点
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k)
{
if(head == NULL) return NULL;
ListNode* p = head;
int count = 0;
//计算链表的总节点数
while(p)
{
count++;
p = p->next;
}
int nodes = count - k; //不需要返回的节点数
for(int i=0;i<nodes;i++)
{
head = head->next;
}
return head;
}
};
方法二:双指针(遍历一次)
1、初始化双指针 left 和 right,都指向链表的头节点
2、指针 right 先向走 k 步,到达 k + 1 节点位置
3、双指针 left 和 right 同时向前移动,直到前指针 right 指向 NULL
4、最后返回 left
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k)
{
if(head == NULL) return NULL;
ListNode* left = head,*right = head;
for(int i = 0; i < k; i++)
{
right = right->next;
}
while(right != NULL)
{
right = right->next;
left = left->next;
}
return left;
}
};