mirror of
https://github.com/krahets/LeetCode-Book.git
synced 2026-01-12 00:19:02 +08:00
4.0 KiB
Executable File
4.0 KiB
Executable File
解题思路:
第一时间想到的解法:
- 先遍历统计链表长度,记为
n; - 设置一个指针走
(n-cnt)步,即可找到链表倒数第cnt个节点;
使用双指针则可以不用统计链表长度。
下图中的
k对应本题的cnt。
算法流程:
- 初始化: 前指针
former、后指针latter,双指针都指向头节点head。 - 构建双指针距离: 前指针
former先向前走cnt步(结束后,双指针former和latter间相距cnt步)。 - 双指针共同移动: 循环中,双指针
former和latter每轮都向前走一步,直至former走过链表 尾节点 时跳出(跳出后,latter与尾节点距离为 $cnt-1$,即latter指向倒数第cnt个节点)。 - 返回值: 返回
latter即可。
代码:
class Solution:
def trainingPlan(self, head: ListNode, cnt: int) -> ListNode:
former, latter = head, head
for _ in range(cnt):
former = former.next
while former:
former, latter = former.next, latter.next
return latter
class Solution {
public ListNode trainingPlan(ListNode head, int cnt) {
ListNode former = head, latter = head;
for(int i = 0; i < cnt; i++)
former = former.next;
while(former != null) {
former = former.next;
latter = latter.next;
}
return latter;
}
}
class Solution {
public:
ListNode* trainingPlan(ListNode* head, int cnt) {
ListNode *former = head, *latter = head;
for(int i = 0; i < cnt; i++)
former = former->next;
while(former != nullptr) {
former = former->next;
latter = latter->next;
}
return latter;
}
};
本题没有 cnt> 链表长度的测试样例 ,因此不用考虑越界。考虑越界问题的代码如下:
class Solution:
def trainingPlan(self, head: ListNode, cnt: int) -> ListNode:
former, latter = head, head
for _ in range(cnt):
if not former: return
former = former.next
while former:
former, latter = former.next, latter.next
return latter
class Solution {
public ListNode trainingPlan(ListNode head, int cnt) {
ListNode former = head, latter = head;
for(int i = 0; i < cnt; i++) {
if(former == null) return null;
former = former.next;
}
while(former != null) {
former = former.next;
latter = latter.next;
}
return latter;
}
}
class Solution {
public:
ListNode* trainingPlan(ListNode* head, int cnt) {
ListNode *former = head, *latter = head;
for(int i = 0; i < cnt; i++) {
if(former == nullptr) return nullptr;
former = former->next;
}
while(former != nullptr) {
former = former->next;
latter = latter->next;
}
return latter;
}
};
复杂度分析:
- 时间复杂度
O(n):n为链表长度;总体看,former走了n步,latter走了(-cnt)步。 - 空间复杂度
O(1): 双指针former,latter使用常数大小的额外空间。








