Leetcode第142题—环形链表Ⅱ

本次写的题目是环形链表Ⅱ,为LeetCode里面的题目,让我们来康康是如何解出这道题目的吧,各位尚没有思路的小伙伴可以跟随着博主的解题思路一步步来,感受一下😎

🌱分析阶段

在本题中,要解决问题,首先要先想明白:如果已知有一个链表,而我们要判断其是否成环,那么要怎么判断呢?

 这个问题解决要用到的技巧就是快慢结点,本类的问题归根就是追击问题,如果成了环,那么快结点两步两步走,慢结点一步一步走,若有环,都在同一个圈内,那么总能追上。

拓展🧐:那么如果说我们想要快一点,可不可以将快结点设置三步三步走,甚至说是多几步这样子走呢?

答案是不行的~例如我们要快结点三步三步走,那么很可能会一直错过相遇喔😫

在明白了追击问题后,我们可以得出总结:追击问题中最快且最稳定的方法是快结点路程为慢结点路程的两倍✨

 之后为了弄明白要怎样获得成环的最初位置,我们设置下面几个参数:L—从链表头结点到成环最初结点位置        C—环的长度        Y—快慢两结点相遇位置到成环最初结点位置(从顺时针看)

我们都知道快结点走过的路程是慢结点的两倍,由此我们可以得出 2*slow = fast  这样的抽象公式(用于之后演算)  

先假如慢结点进入的第一圈就和快结点遇到了,那么可以推算出下面的结论👇:

那么如果慢结点是在快结点转很多圈后慢结点才进入环的呢?还会有这样的规律出现么?下面请看博主再次演算的过程👇:

 那么我们知道了 头结点到最初成环位置的距离 = 两结点相遇位置到最初成环位置的距离 这个规律有什么用处呢?在这里博主先卖个关子,浅画一个图,看看有没有小伙伴能get到什么😎

由此图,我们已经有fast结点出现,在slow和fast相遇后fast在相遇的位置上,那么如果此时我们将slow放回链表最初位置,然后fast和slow链表都同时一步一步走,那么最后,两个结点的相遇就会为最初的成环位置上了😎✨✨✨ 

 📢总结:要完成本题,大致思路十分简单:①制造快慢结点相遇;②相遇后将慢结点放回链表头结点位置,与快结点同时一步步走,相遇处即为成环位置;但是其中的推测过程值得我们反复思考。


🌱代码阶段

在知道大致思路以后写代码是相对于较容易的事情,但是在知道大致思路后,正式写代码前,我们要先考虑有无特殊情况出现,但由于这题的代码过于简单,只是分析问题的过程比较复杂,所以没有什么需要特殊考虑的。具体的细节请看下面代码~👇

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head==null) return null;
        ListNode fast = head;
        ListNode slow = head;
        //判断有无成环并让快慢结点相遇
        while(fast!=null&&fast.next!=null){
            fast= fast.next.next;
            slow = slow.next;
            if(fast==slow) break;
        }
        //在退出上面循环后,有可能是因为没有成环链表而导致退出的
        //下面判断是不是因为没有成环链表才退出的循环
        if(fast==null||fast.next==null){
            return null;
        }
        //判断有成环链表后,继续最后一步,寻找成环处
        slow = head;
        while(slow!=fast){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}

至此,全部的代码就写完了,让我们运行逝逝吧~

nice😎✨✨


制作本篇文章实在不易,要是有帮助到您的话请不要厉色点赞哦🥺你的每一个点赞评论都是对博主莫大的鼓励🥺🥺

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C每日一练中的环形链表Ⅱ问是指LeetCode专栏中的第142。该问的目标是找到给定链表中的环的入口节点。解决这个问的一种常用方法是使用快慢指针。 快慢指针解法中,快指针的步数是慢指针的两倍,即慢指针一次走一步,快指针一次走两步。两个指针从链表的起始位置开始运行,如果链表中存在环,则快指针最终会追上慢指针,二者会在环中相遇。如果链表不带环,则快指针会率先走到链表的末尾。这种思路可以通过在纸上画图来更好地理解。 在解决环形链表Ⅱ问时,我们可以按照以下步骤进行操作: 1. 定义快慢指针,初始时都指向链表的头节点。 2. 快指针一次走两步,慢指针一次走一步,直到两个指针相遇或快指针到达链表末尾。 3. 如果快指针到达链表末尾,则说明链表中没有环,直接返回null。 4. 如果快慢指针相遇,则说明链表中存在环。 5. 重新定义一个指针,从链表的头节点开始,与慢指针同时移动,每次移动一步,直到两个指针再次相遇。 6. 当两个指针再次相遇时,它们所指向的节点就是环的入口节点。 通过以上步骤,我们可以找到给定链表中环的入口节点。注意,在实际编码中,需要考虑边界条件和特殊情况的处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【LeetCode】每日一链表部分经典型](https://blog.csdn.net/qq_63320529/article/details/130697933)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值