leetcode刷题, 总结,记录, 备忘142

leetcode142

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?

这个题目是在一版的基础上,需要返回循环的起点,我自己是不会做的!参考了别人博客,并自己进行了深入的思考,下面娓娓道来。


首先看图,画的不好见谅。还是使用快慢指针的方法,分别为1,2表示。一个每次走一步,一个每次走2步。在图中这个情况下,慢指针需要走3步才能到达循环开始的节点处,而此时的快指针已经进入了循环。由图中可知,此时1指针才刚到循环的开始处,而2指针已经在循环里走了3步。那该如何得到走多少步之后2个指针才能重合呢。假设需要走x步才能重合,现在1指针在循环中的位置为0,2指针为3。那么0+x 和 2x+3 的值对循环圈的长度,即4,取模之后的结果应该是相同的,表示处在环上的某一个相同位置上。考虑到2指针由于步长是2,很有可能在走过x步之后已经绕了一圈,所以这里我做个假设,做了个等式,x = 2x + 3 - 4, 即x = 4 - 3。就是使用环长减去头节点到环开始处的长度,这个步数的计算方法是我在别人博客里看来的,但是人家写的时候并没有做太多解释,前文中的那些推论都是我自己画图琢磨时的一些感悟,若有错误,轻喷。由此可得到需要走多少步,2个指针会重合,之后你就会神奇的发现,由于环长是4,x为1,慢指针和快指针走了一次之后就重合了,此时,慢指针如果需要再走到,环头,还需要4-x步,即3步,但是各位有没发现x就是由4-3,环长减去头节点到环头的长度得来的,所以忽然发现,重合点的位置到环头的距离与头节点到环头的距离是一样的,由此就可以轻松的找到环头节点的指针了。之后你也会发现在环中重合一次之后,下一次重合是5步之后,即x加上环长4。我觉得这题还真需要好好画图推演,找到相应的定理才好理解,,,但是其中的缘由是什么我也并步太清楚,只是自己做出了一些推断。

可能有 比较细心的同学会说,如果是环的长度比头节点到环头的距离小呢,想得到x步就是负数了吗,,我也考虑到这个问题了,只需将环长翻倍即可,乘2不够就乘3,然后再减,即可得到需要多少步可以重合。具体的图就不画了,画的太丑了。

我也不是什么数学高手,,只是个破代码屌丝,,说实话这个题目我是真不会做,全是去百度查的,然后看别人的博客,听人家说的那些定理,然后步理解,自己画图然后慢慢走几遍,才算有点非常浅薄甚至可能不正确的理解,仅供大家参考,说错的地方也勿喷,,,,欢迎交流,下面上代码,还是比较容易理解的,主要是了解这个快慢指针与环的原理就行了。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if (head == NULL) {
            return NULL;
        }
        ListNode * slow = head;
        ListNode * fast = head;
        
        while (slow->next && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
            if (!fast) {
                break;
            }
            
            if (slow == fast) {
                fast = head;
                while (fast != slow) {
                    fast = fast->next;
                    slow = slow->next;
                }
                return fast;
            }
        }
        
        return NULL;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值