【Lintcode】1088. Redundant Connection

題目地址:

https://www.lintcode.com/problem/redundant-connection/description

給定一個無向圖,其頂點以1n1\sim n標記。已知僅去掉一條邊,這個圖就能成爲一棵樹,求這條邊。若有多個解,則返回下標最後的那個。

思路是並查集。由於這個圖去掉一條邊就成爲一棵樹,而對於樹,有V1=EV-1=E,所以我們知道對於這個圖,頂點的個數就等於邊數。接着開始遍歷所有的邊,遇到一條邊就union其兩個端點。若發現有兩個端點之前已經連通,說明這條邊可以去掉,返回之即可。代碼如下:

public class Solution {
    
    class UnionFind {
        private int[] parent, rank;
        int group;
        
        public UnionFind(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
                rank[i] = 1;
            }
            
            group = n;
        }
        
        public int find(int p) {
            if (p != parent[p]) {
                parent[p] = find(parent[p]);
            }
            
            return parent[p];
        }
        
        public boolean union(int p, int q) {
            int pRoot = find(p), qRoot = find(q);
            if (pRoot == qRoot) {
                return false;
            }
            
            if (rank[pRoot] < rank[qRoot]) {
                parent[pRoot] = qRoot;
            } else if (rank[pRoot] > rank[qRoot]) {
                parent[qRoot] = pRoot;
            } else {
                parent[pRoot] = qRoot;
                rank[qRoot]++;
            }
            
            return true;
        }
    }
    
    /**
     * @param edges: List[List[int]]
     * @return: List[int]
     */
    public int[] findRedundantConnection(int[][] edges) {
        // write your code here
        if (edges == null || edges.length == 0) {
            return null;
        }
        
        UnionFind uf = new UnionFind(edges.length);
        for (int[] edge : edges) {
        	// 發現了union失敗了,即這兩個頂點已經連通了,則返回之
            if (!uf.union(edge[0] - 1, edge[1] - 1)) {
                return edge;
            }
        }
        
        return null;
    }
}

時間複雜度O(nlogn)O(n\log ^* n),空間O(n)O(n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章