【面试题】链表成环?求入环点?证明+代码?必须安排~

这篇具有很好参考价值的文章主要介绍了【面试题】链表成环?求入环点?证明+代码?必须安排~。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【面试题】链表成环?求入环点?证明+代码?必须安排~

👦个人主页:@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之间的距离是Nslow进环后,fast就开始追加slowslow每走一步,fast就会走2步,它们之间的距离就会逐渐缩小1。
fastslow之间的距离变化:
N — 起始距离
N-1
N-2

3
2
1
0 – 相遇
直到N的距离逐渐缩小到0,它们就一定能相遇。

  • 假设慢指针slow走1步,快指针fast走x步(x ≥ 3),它们会相遇还是会错过?请证明。

【证明】
假设x = 3,与上面同样的道理,设slow进环时,fastslow之间的距离为Nslow进环后,fast就开始追击slowslow走1步,fast走3步,它们之间的距离就会逐渐缩小2。但这次的证明与上一个不同,因为上一个之间的距离逐渐缩小1,所以无论N的值是多少,N最后一定会被减到0。而这次证明需要对N进行分类讨论,N是偶数或奇数。
fastslow之间的距离变化:
①当N是偶数时,再加上fastslow的距离逐渐缩小2,最后的它们之间的距离一定为0
N — 起始距离
N - 2
N - 4

4
2
0 – 相遇
②当N是奇数时
N
N - 2
N - 4

3
1
-1
当走到最后,fastslow之间的距离为-1,这说明fast在追加slow的时候超过slow了,此时fastslow之间的距离就是周长 - 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 证明

面试官:你怎么知道一个指针从相遇点开始走,另一个指针从起始点开始走,它们最终会在入环点相遇。请证明

【面试题】链表成环?求入环点?证明+代码?必须安排~
【证明过程】

  1. 设起始点->入环点的距离为L
    入环点->相遇点的距离为X
    环的长度为C
  2. 所以,慢指针移动的距离:L + X
    快指针移动的距离:L + nC + X
  • 为什么快慢指针相遇时,慢指针的移动距离小于环长,换句话说,为什么慢指针的移动距离不是L + X + n
    答:考虑最坏的情况下,当慢指针入环时,快指针敲好在慢指针前面,快指针则需要走C - 1步才能与慢指针相遇,所以无论对于任何情况,快指针到慢指针的距离都不会超过C - 1步,所以,慢指针的移动距离更不会大于环长
    【面试题】链表成环?求入环点?证明+代码?必须安排~

  • 快指针的移动距离不能写成L + C + X
    答:因为起始点到入环点和相遇点到入环点有可能不相等。
    【面试题】链表成环?求入环点?证明+代码?必须安排~

  1. 规定快指针走2步,慢指针走1步。所以,快指针的移动距离是慢指针的2倍。
    所以,不难可以列出等式:2(L + X) = L + nc + X
  2. 化简等式得:L = nC - X --> 意味着:一个指针从相遇点走,另一个指针从起始点走,它们最后会在入口点相遇。

5、总结

若证明过程有啥问题的,欢迎大佬指出,虚心接受orz文章来源地址https://www.toymoban.com/news/detail-409391.html

到了这里,关于【面试题】链表成环?求入环点?证明+代码?必须安排~的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包