目录:
目的
链表{1,2,3,4,5},倒数最后2个节点是{4,5}。
思路
这个任务是找到链表中倒数最后k个结点。可以看作这是一场真心话大冒险。游戏主持人会随机抽一个数字 k,然后找出从最后数起的第 k个玩家。 这个玩家和他之后的所有人都要说出一个令人惊讶的秘密,接受惩罚!由于人数太多,一个个数太慢,于是主持人召唤了两个助手:“胖胖(慢指针)”和“瘦瘦(快指针)”。这两人行动敏捷,专门负责快速定位玩家,确保游戏更高效。
胖瘦仙童最完美CP:
-
瘦瘦(fast 指针):
- 职责:先抢数k个人,确保胖胖在开始时不会浪费时间。
- 行为:他直接从第一玩家
pHead
数,挨个数走到下一个玩家的位置(即fast = fast.next
)。 - 边界条件:如果玩家人数小于 k,那么直接游戏结束,返回
None
。
-
胖胖(slow 指针):
- 职责:稳定地跟随瘦瘦,但始终保持 k 个玩家的距离。
- 行为:也从第一玩家
pHead
数,当瘦瘦数结束时,胖胖刚好停在倒数第 k 个玩家的位置。
游戏开始:
1. 瘦瘦先抢数
瘦瘦一开始从第一个玩家
pHead
数, 先抢数k个玩家,让自己和胖胖之间保持 k 个玩家的距离。2. 胖胖跟着瘦瘦同步行动
瘦瘦完成抢数后,胖胖也开始行动。此时两人同步前进:
- 瘦瘦继续每次数一个玩家fast = fast.next,直到数到最后。
- 胖胖紧跟其后,数数仔细,每个玩家挨个数slow = slow.next。
宣布倒霉蛋:
- 当瘦瘦到达链表尾部(
fast == None
),胖胖正好停在从最后数第 k 个玩家的位置。 - 胖胖大声宣布:“你和你后面的所有倒霉蛋们!快去接受真心话大冒险吧!” return slow。
复杂度
-
时间复杂度:O(n)
- 瘦瘦先抢数 k 个玩家,接着两人同步数 n−k个玩家,总共数一遍(遍历一次链表)。
-
空间复杂度:O(1)
- 只用了胖瘦仙童(两个指针变量),不多花内存。
记忆秘诀
- 瘦瘦抢数,保持领先: 瘦瘦(快指针)心疼胖胖,先走 k 步。
- 胖胖跟随,锁定目标: 胖胖和瘦瘦一起同步行动,直到瘦瘦停在终点。
- 精确定位,宣布结果: 胖胖停下时的位置,就是倒数第 k个玩家。
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
if not pHead or k <= 0:
return None # 如果链表为空或k无效,返回None
fast = pHead
slow = pHead
# 快指针先走k步
for _ in range(k):
if fast:
fast = fast.next
else:
return None # 如果链表长度小于k,返回None
# 快慢指针一起走,直到快指针到达链表末尾
while fast:
fast = fast.next
slow = slow.next
# 此时slow指向倒数第k个节点
return slow
* 欢迎大家探讨新思路,能够更好的理解和记忆