1. 程式人生 >實用技巧 >其它 >LeetCode 每日一題684. 冗餘連線

LeetCode 每日一題684. 冗餘連線


技術標籤:每日一題leetcode圖論java演算法資料結構

684. 冗餘連線

在本問題中, 樹指的是一個連通且無環的無向圖。

輸入一個圖,該圖由一個有著N個節點 (節點值不重複1, 2, …, N) 的樹及一條附加的邊構成。附加的邊的兩個頂點包含在1到N中間,這條附加的邊不屬於樹中已存在的邊。

結果圖是一個以邊組成的二維陣列。每一個邊的元素是一對[u, v] ,滿足 u < v,表示連線頂點u 和v的無向圖的邊。

返回一條可以刪去的邊,使得結果圖是一個有著N個節點的樹。如果有多個答案,則返回二維陣列中最後出現的邊。答案邊 [u, v] 應滿足相同的格式 u < v。

示例 1:

輸入: [[1,2], [1,3], [2,3]]
輸出: [2,3]
解釋: 給定的無向圖為:
  1
 / \
2 - 3

示例 2:

輸入: [[1,2], [2,3], [3,4], [1,4], [1,5]]
輸出: [1,4]
解釋: 給定的無向圖為:
5 - 1 - 2
    |   |
    4 - 3

注意:

  • 輸入的二維陣列大小在 3 到 1000。
  • 二維陣列中的整數在1到N之間,其中N是輸入陣列的大小。

方法一:並查集

首先,感謝 leecote!

這個月人稱「圖論月」,從最開始複製貼上,到現在已經能 5 分鐘寫完基礎「並查集」~

解題思路

  • 「無向圖」可以用並查集解決,此題是找出 「多餘的連線」
  • 搞清楚如何定義 「多餘的連線」,問題基本就解決了

就用示例 1 舉例:

輸入:[[1,2], [1,3], [2,3]]

step 1:[1,2]加入並查集,2 的父親是 1
  1
 / 
2  
step 2:[1,3]加入並查集,3 的父親是 1
  1
 / \
2   3
step 3:[2,3] 加入並查集前,發現 2 和 3 已經有共同的父親 1,說明這條線是多餘的。
  • 也就是說,數字對在加入並查集前,已經有共同的父親了,說明這條連線就是「多餘的連線」

參考程式碼

public int[] findRedundantConnection(int[][] edges) {
    int n = edges.length;
    UnionFind unionFind = new UnionFind(n + 1);
    for (int[] e : edges) {
        // 合併前就有共同的父親,說明這條是多餘的連線
        if (unionFind.find(e[0]) == unionFind.find(e[1])) {
            return e;
        }
        unionFind.union(e[0], e[1]);
    }
    return new int[2];
}

// 並查集
class UnionFind {
    public int[] parent;
    // 初始化,自己就是自己的父親
    public UnionFind(int n) {
        parent = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] =i;
        }
    }
    // 合併數字對
    public void union(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX == rootY) {
            return;
        }
        parent[rootX] = rootY;
    }
    // 找數字 x 的父親
    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
}

執行結果

LeetCode 每日一題684. 冗餘連線