【算法演练】找出链表中环的入口

241 阅读1分钟

如果一个链表中包含有环,如何找出这个环的入口?

例如:链表中环的入口为3.

思路:

1.我们得确定链表中有环。 2 去找环的入口

  • 使用两个指针,一快一慢,快指针每次走2步,慢指针每次走1步,当快指针都指向null了还没有追上慢指针,这就说明链表无环。
  • 确定链表中环的节点个数,当第一步两个节点相遇后,我们这时候开始找环中节点个数。从相遇节点开始,往后面迭代做计数,当再次回到这个节点的时候,走的步数就是环中节点的个数
  • 知道环中节点的个数后比如为k个,我们仍然使用快慢两个指针,先让快指针走k步,然后快慢指针一起走,当两节点相遇的时候,该节点就是环的入口。
  // 查找链表环的入口
    public void findCycleNodeEntry(Node head){
        Node firstMetting = hasCycle(head);
        if (firstMetting == null)return; //没有环,
        //找环中节点的个数
        Node p = firstMetting;
        int count = 0;
        p = p.next;
        count++;
        while (p != firstMetting ){
            p = p.next;
            count++;
        }

        //从表头开始,快指针先走count步
        Node fast = head;
        Node slow = head;

        for (int i = 0; i < count; i++){
            fast = fast.next;
        }

        while (fast != slow){
            fast = fast.next;
            slow = slow.next;
        }

        System.out.println(fast.data);

    }
    
    
    //判断是否有环,返回相遇节点
    public Node hasCycle(Node head){
        if (head == null || head.next == null)return null;
        Node fastN = head;
        Node slowN = head;
        while (fastN != null && slowN != null){
            if (fastN.next == null){
                return null;
            }
            fastN = fastN.next.next;
            slowN = slowN.next;
            if (fastN == slowN){
                System.out.println("has cycle");
                return fastN;
            }
        }
        return null;
    }