注意点:
1.快慢指针,都从链表头出发,快指针先行k步,达不到k步说明链表过短,返回空链表。
2.快慢指针同步向后,快指针先到底,慢指针指向倒数第k个,因为它们之间差了k个元素。
#include <iostream>
using namespace std;
//链表节点
struct ListNode{
int val;
ListNode* next;
//初始化
ListNode(int x) : val(x), next(NULL){}
};
//找到链表倒数第k个节点
ListNode* FindKthToTail(ListNode* pHead, int k){
int n = 0;
ListNode* fast = pHead;
ListNode* slow = pHead;
//快指针
for(int i = 0; i < k; i++){
if (fast != NULL)
fast = fast->next;
else
//达不到k,说明链表长度过短,返回空链表
return slow = NULL;
}
//快慢指针同步,快指针先到底,慢指针指向倒数第k个元素
while (fast != NULL){
fast = fast->next;
slow = slow->next;
}
return slow;
}
int main()
{
int n,val;
//输入n个节点
while ( cin >> n){
cin >> val;
//输入链表第一个节点
ListNode *head = new ListNode(val);
ListNode *p = head;
//输入链表后续节点
for(int i = 1; i < n; i++)
{
cin >> val;
ListNode *q = new ListNode(val);
//连接
p->next = q;
p = p->next;
}
//找到第k个位置
int k;
cin >> k;
//边界条件如果等于0直接返回0;
if( k == 0)
cout << 0 << endl;
else{
//找到第k个节点
p = FindKthToTail(head, k);
//只有返回不NULL才输出
if (p != NULL)
cout << p->val << endl;
}
}
return 0;
}
- 时间复杂度:O(n),总共遍历n个链表元素
- 空间复杂度:O(n),链表空间属于必要空间,无额外空间