链表有环问题 【剑指offer】

1.有一个单向链表,链表当中有可能出现“环”,就像下图这样。如何用程序判断出这个链表是有环链表?

%e9%93%be%e8%a1%a8%e5%9b%be1

      对于判断有环问题,能判断后面的节点和前面节点有没有相等的,这里相等是指是同一个对象,也就只能由一个后继节点,对于这种情况,我们可以设置两个节点,都从头节点开始,一个节点走两步,fast .next.next,一个节点走一步,即slow .next,如果有环,那么就会有fast==low的情况,也就能判断出来是否有环。

2.如何知道环的长度?

       记录下问题1的相遇点,slow、fast从该点开始,再次相遇时slow所经过的节点数就是环的长度。从环上的任意一点开始,slow、fast再次相遇时slow经过的节点数就是环的长度,因为此时slow、fast起始距离为环长,速度差为1。选择问题1的相遇点为起始点是为了确保起始点为环上的一点。

3.如何找出环的连接点在哪里?

     设问题1中的相遇点为m1,赋值p=m1,q=h,其中h为链表头结点,然后p,q每次1步向前运动,p,q再次相遇所在的位置就是环的入口节点(环的连接点)。

     如图中所示,设链起点到环入口点间的距离为x,环入口点到问题1中fast与slow重合点的距离为y,又设在fast与slow重合时fast已绕环n周(n>0),且此时low移动总长度为s,则fast移动总长度为2s,环的长度为r。则
        s + nr = 2s,n>0      ①
        s = x + y               ②
       由①式得  s = nr                 
       代入②式得
       nr = x + y
       x = nr - y 

此时我们就能得出结论了,从重合点和头节点向下走,两者相等的时候为入口。

下面给出代码:问题是给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

需要先判断是否有环,如果有再判断环的入口结点,没有就返回null

public class Main {
    public static void main(String[] args) {
        ListNode node = new ListNode(1);
        Solution solution = new Solution();
        ListNode node1 = solution.EntryNodeOfLoop(node);
        System.out.println(node1);
    }
}
class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode fast = pHead;
        ListNode slow = pHead;
        int flag = 0;  //标记,0代表没环
        while (fast != null) {  //如果fast为空就不可能有环
            if (fast.next == null || fast.next.next == null) {
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {//如果相同就说明有环,直接跳出循环
                flag = 1;
                break;
            }
        }

        if (flag == 0) {  //判断之后没环就返回
            return null;
        }
        while (true) {  //判断环的入口位置
            if (pHead == slow) {
                return slow;
            }
            pHead = pHead.next;
            slow = slow.next;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_35634181/article/details/82055091