主题
想象兔子和乌龟在同一跑道上,一个速度快、另一个速度慢。如果跑道有环,兔子必然在一段时间后追上乌龟。对于链表来说,如果在链表中引入两个以不同速度(一个比另一个快一倍)前进的指针,在链表存在环的情况下,这两个指针必定会相遇。
视频讲解:【基础算法精讲 07】,制作不易,欢迎点赞!
⚠注意:代码比较两个节点的时候,比较的是内存地址是否一致,并没有比较节点的 val。
答疑
问:兔子会不会「跳过」乌龟,从来不会和乌龟相遇呢?
答:这是不可能的。如果有环的话,那么兔子和乌龟都会进入环中。这时用「相对速度」思考,乌龟不动,兔子相对乌龟每次只走一步,这样就可以看出兔子一定会和乌龟相遇了。
问:为什么代码的
答:
python
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
slow = fast = head # 乌龟和兔子同时从起点出发
while fast and fast.next:
slow = slow.next # 乌龟走一步
fast = fast.next.next # 兔子走两步
if fast is slow: # 兔子追上乌龟(套圈),说明有环
return True
return False # 访问到了链表末尾,无环cpp
// C++ 版待补充cpp
class Solution {
public:
bool hasCycle(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head; // 乌龟和兔子同时从起点出发
while (fast && fast->next) {
slow = slow->next; // 乌龟走一步
fast = fast->next->next; // 兔子走两步
if (fast == slow) { // 兔子追上乌龟(套圈),说明有环
return true;
}
}
return false; // 访问到了链表末尾,无环
}
};复杂度分析
- 时间复杂度:
,其中 是链表的长度。理由见 本题视频讲解【基础算法精讲 07】。 - 空间复杂度:
。
进阶题目
返回入环口。见 142. 环形链表 II。
分类题单
- 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
- 二分算法(二分答案/最小化最大值/最大化最小值/第K小)
- 单调栈(基础/矩形面积/贡献法/最小字典序)
- 网格图(DFS/BFS/综合应用)
- 位运算(基础/性质/拆位/试填/恒等式/思维)
- 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
- 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
- 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
- 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
- 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
- 链表、二叉树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA/一般树)
- 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)
欢迎关注 B站@灵茶山艾府