含有环的单链表的入环口求解

今天做到了这个题目,重温了下左神的方法,同时也和师兄讨论了下,为什么在第二次相遇时,就是其入环口。

求解入环口的方法:

快慢指针法(左神)

步骤:

  1. 设置两个指针一个快指针quick,一个慢指针slow(快指针一次走两步,慢指针一次走一步,如果他们能相遇则说明有环)
  2. 相遇后,快指针重新回到头结点head,之后,两个结点一起前进,均一次走一步,再次相遇处则为入环口。

代码

public static Node getCircleEntrance(Node head) {
    if (head.next == null || head.next.next == null) {
        return null;
    }
    Node quick = head.next.next;
    Node slow = head.next;
    while (quick != slow) {
        if (slow.next == null || quick.next.next == null) {
            return null;
        }
        quick = quick.next.next;
        slow = quick.next;
    }
    //相等时说明有环
    quick = head;
    while (quick != slow) {
        quick = quick.next;
        slow = slow.next;
    }
    return slow;
}

当时写代码时,在想为什么第二次相遇时就是入环点呢?讨论了一波,总结如下:

在这里插入图片描述

同时,也在考虑,如果不用快慢指针,是否可以用HashSet集合来存储每一个节点,如果有重复的节点被存入,返回该节点即可。(这样的话会增加空间开销)

public static Node circleIndex(Node head){
    HashSet<Node> set = new HashSet<>();
    Node cur = head;
    while(cur.next != null){
        if(set.contains(cur)){
            return cur;
        }
        set.add(cur);
        cur = cur.next;
    }
    return null;
}

猜你喜欢

转载自blog.csdn.net/weixin_41055558/article/details/89409722