LeetCode-142-環形連結串列 II

雄獅虎豹 發表於 2022-01-26
LeetCode

環形連結串列 II

題目描述:給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null。

為了表示給定連結串列中的環,我們使用整數 pos 來表示連結串列尾連線到連結串列中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該連結串列中沒有環。注意,pos 僅僅是用於標識環的情況,並不會作為引數傳遞到函式中。

說明:不允許修改給定的連結串列。

進階:

你是否可以使用 O(1) 空間解決此題?

示例說明請見LeetCode官網。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/probl...
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解法一:雜湊表
HashSet判斷節點是否重複。
解法二:雙指標法
使用快慢節點,如果有環,則這兩個節點必回相遇。
import java.util.HashSet;
import java.util.Set;

public class LeetCode_142 {
    /**
     * 雜湊
     *
     * @param head
     * @return
     */
    public static ListNode detectCycle(ListNode head) {
        if (head == null) {
            return null;
        }
        Set<ListNode> nodes = new HashSet<>();
        nodes.add(head);
        while (head.next != null) {
            // 如果next節點在雜湊表中出現過,說明成環了, 而且next節點肯定是入環點,直接返回
            if (nodes.contains(head.next)) {
                return head.next;
            }
            nodes.add(head.next);
            head = head.next;
        }
        return null;
    }

    /**
     * 雙指標法
     *
     * @param head
     * @return
     */
    public static ListNode detectCycle2(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode slow = head, fast = head;
        while (fast != null) {
            slow = slow.next;
            if (fast.next != null) {
                fast = fast.next.next;
            } else {
                return null;
            }
            if (fast == slow) {
                ListNode ptr = head;
                while (ptr != slow) {
                    ptr = ptr.next;
                    slow = slow.next;
                }
                return ptr;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        ListNode head = new ListNode(3);
        head.next = new ListNode(2);
        head.next.next = new ListNode(0);
        head.next.next.next = new ListNode(-4);
        head.next.next.next.next = head.next;

        System.out.println(detectCycle(head) == null ? -1 : detectCycle(head).val);
        System.out.println(detectCycle2(head) == null ? -1 : detectCycle2(head).val);
    }
}
【每日寄語】 人世間不可預料的事情太多了,但是不管怎樣,社會還會照樣執行。一個人不管有多大的成就,在世界萬物中都是非常渺小的,所以要珍惜每一分每一秒。