👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:Leetcode + 面试/笔试
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨
一、环形链表I
1.1 题目描述
LeetCode链接:环形链表I
1.2 思路 + 代码实现
【思路】
可以使用快慢指针,然后转化成追击问题。快指针一次走2步,慢指针一次走1步,如果链表成环,快指针就一定能追上慢指针。
此篇博客详细讲述了快慢指针 —> 点我跳转
【代码实现】
bool hasCycle(struct ListNode *head)
{
struct ListNode* fast = head,*slow = head;
while (fast && fast->next)
{
//快指针一次走2步,慢指针一次走1步
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
return true;
}
return false;
}
1.3 证明
写出以上代码并不难,关键在于证明。
- 为什么慢指针
slow
走1步,快指针fast
走2步,它们一定就能相遇?有没有可能会错过?请证明。
【证明】
假设慢指针slow
进环时,设快指针fast
和慢指针slow
之间的距离是N
,slow
进环后,fast
就开始追加slow
,slow
每走一步,fast
就会走2步,它们之间的距离就会逐渐缩小1。fast
和slow
之间的距离变化:
N — 起始距离
N-1
N-2
…
3
2
1
0 – 相遇
直到N的距离逐渐缩小到0,它们就一定能相遇。
- 假设慢指针slow走1步,快指针fast走x步(x ≥ 3),它们会相遇还是会错过?请证明。
【证明】
假设x = 3
,与上面同样的道理,设slow
进环时,fast
和slow
之间的距离为N
。slow
进环后,fast
就开始追击slow
,slow
走1步,fast
走3步,它们之间的距离就会逐渐缩小2。但这次的证明与上一个不同,因为上一个之间的距离逐渐缩小1,所以无论N
的值是多少,N
最后一定会被减到0。而这次证明需要对N
进行分类讨论,N
是偶数或奇数。fast
和slow
之间的距离变化:
①当N
是偶数时,再加上fast
和slow
的距离逐渐缩小2,最后的它们之间的距离一定为0
N — 起始距离
N - 2
N - 4
…
4
2
0 – 相遇
②当N是奇数时
N
N - 2
N - 4
…
3
1
-1
当走到最后,fast
和slow
之间的距离为-1,这说明fast
在追加slow
的时候超过slow
了,此时fast
和slow
之间的距离就是周长 - 1
(往后假设周长为C),相当于进入新一轮追击。这里就要再判断C - 1
是奇数还是偶数,如果C - 1
是偶数代表一定能追的上,否则就追不上。
二、环形链表II
2.1 题目描述
LeetCode链接:环形链表II
2.2 思路 + 代码
【思路】
先给出结论:一个指针从相遇点开始走,另一个指针从起始点开始走。它们最终会在入环点相遇。 后面会给出i详细的证明过程
【代码实现】
struct ListNode *detectCycle(struct ListNode *head)
{
//快慢指针找相遇点
struct ListNode* fast = head,*slow = head;
while (fast && fast->next )
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
//相遇点(slow改成fast也行)
struct ListNode* meet = slow;
//记录起始点
struct ListNode* start = head;
while (start != meet)
{
meet = meet->next;
start = start->next;
}
//最终他们会在入环点相遇
return meet;
}
}
return NULL;
}
2.3 证明
面试官:你怎么知道一个指针从相遇点开始走,另一个指针从起始点开始走,它们最终会在入环点相遇。请证明
【证明过程】
- 设起始点->入环点的距离为
L
入环点->相遇点的距离为X
环的长度为C
- 所以,慢指针移动的距离:
L + X
快指针移动的距离:L + nC + X
为什么快慢指针相遇时,慢指针的移动距离小于环长,换句话说,为什么慢指针的移动距离不是
L + X + n
答:考虑最坏的情况下,当慢指针入环时,快指针敲好在慢指针前面,快指针则需要走C - 1
步才能与慢指针相遇,所以无论对于任何情况,快指针到慢指针的距离都不会超过C - 1
步,所以,慢指针的移动距离更不会大于环长快指针的移动距离不能写成
L + C + X
答:因为起始点到入环点和相遇点到入环点有可能不相等。
文章来源:https://www.toymoban.com/news/detail-409391.html
- 规定快指针走2步,慢指针走1步。所以,快指针的移动距离是慢指针的2倍。
所以,不难可以列出等式:2(L + X) = L + nc + X
- 化简等式得:
L = nC - X
--> 意味着:一个指针从相遇点走,另一个指针从起始点走,它们最后会在入口点相遇。
5、总结
若证明过程有啥问题的,欢迎大佬指出,虚心接受orz文章来源地址https://www.toymoban.com/news/detail-409391.html
到了这里,关于【面试题】链表成环?求入环点?证明+代码?必须安排~的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!