題目地址:
https://www.lintcode.com/problem/redundant-connection/description
給定一個無向圖,其頂點以標記。已知僅去掉一條邊,這個圖就能成爲一棵樹,求這條邊。若有多個解,則返回下標最後的那個。
思路是並查集。由於這個圖去掉一條邊就成爲一棵樹,而對於樹,有,所以我們知道對於這個圖,頂點的個數就等於邊數。接着開始遍歷所有的邊,遇到一條邊就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;
}
}
時間複雜度,空間。