赞
踩
判断一个链表有环,如果有环,返回起点
使用快慢指针的方式,两个指针同时指向头节点,慢指针low一次走一步,快指针fast一次走两步,只要low和fast相遇即说明链表有环
只要快指针和慢指针有相差的步数,但最好是差一步,fast就可以追上low,不一定是low1步,fast2步
如果链表有环,此时fast指针比low指针多走了一倍的路程,此时fast重新指向头节点,low和fast都每次向下走一步,low和fast再次相遇的节点,就是环的入口 为什么?
证明:以下图为例,设在入口前的长度为preLen low与fast 的碰撞点位置为impact 入口位置到碰撞点位置的长度为 impPreLen 从碰撞点到入口的距离为 impProLen ,环的长度为 ringLen, 同时意味着 ringLen = impPreLen + impProLen
=> impPreLen = ringLen - impProLen
可以推理出
根据推理公式可以看出preLen 的长度 = 碰撞点 + n(fastRing - 2lowRing - 1)个环完整圈数
同时 碰撞点出发走n(fastRing - 2lowRing - 1)个环完整圈数 在走一个 impProLen 长度,是正好到达环入口点的
所以最后 fast恢复到 1 步 是走 preLen 长度到入口点是,一定可以和 low指针相碰
public static Node isHasRollLinkedList(Node node) { if (node == null || node.next == null || node.next.next == null) { return null; } Node fast = node.next; Node low = node.next.next; while (fast != low) { if (fast.next == null || fast.next.next == null) { return null; } fast = fast.next.next; low = low.next; } fast = node; while (fast != low) { fast = fast.next; low = low.next; } return low; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。