1、解题思路
- 双指针法:使用两个指针,快指针和慢指针,初始时都指向链表头节点。快指针先移动k步,然后快慢指针同时移动,直到快指针到达链表末尾。此时慢指针指向的节点即为倒数第k个节点。
- 特殊情况处理:如果链表长度小于k,直接返回空链表。
2、代码实现
C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* FindKthToTail(ListNode* pHead, int k) {
// write code here
ListNode* fast = pHead, *slow = pHead;
// 快指针先移动 k 步
for (int i = 0; i < k; ++i) {
if (fast == nullptr) {
return nullptr; // 链表长度小于 k, 返回 空
}
fast = fast->next;
}
// 快慢指针同时移动, 直到快指针到达末尾
while (fast != nullptr) {
fast = fast->next;
slow = slow->next;
}
// 慢指针指向倒数第 k 个节点
return slow;
}
};
Java
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
ListNode fast = pHead, slow = pHead;
// 快指针先移动k步
for (int i = 0; i < k; ++i) {
if (fast == null) {
return null; // 链表长度小于k,返回空
}
fast = fast.next;
}
// 快慢指针同时移动,直到快指针到达末尾
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
// 慢指针指向倒数第k个节点
return slow;
}
}
Python
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param pHead ListNode类
# @param k int整型
# @return ListNode类
#
class Solution:
def FindKthToTail(self, pHead: ListNode, k: int) -> ListNode:
# write code here
fast = slow = pHead
# 快指针先移动k步
for _ in range(k):
if not fast:
return None # 链表长度小于k,返回空
fast = fast.next
# 快慢指针同时移动,直到快指针到达末尾
while fast:
fast = fast.next
slow = slow.next
# 慢指针指向倒数第k个节点
return slow
3、复杂度分析
- 时间复杂度:O(n),只需遍历链表一次。
- 空间复杂度:O(1),仅使用两个指针。