Description:
In this problem, a tree is an undirected graph that is connected and has no cycles.
The given input is a graph that started as a tree with N nodes (with distinct values 1, 2, ..., N), with one additional edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed.
The resulting graph is given as a 2D-array of edges
.
Each element of edges
is a pair [u,
v]
with u < v
, that represents an undirected edge
connecting nodes u
and v
.
Return an edge that can be removed so that the resulting graph is a tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. The answer edge [u,
v]
should be in the same format, with u < v
.
Example 1:
Input: [[1,2], [1,3], [2,3]] Output: [2,3] Explanation: The given undirected graph will be like this: 1 / \ 2 - 3
Example 2:
Input: [[1,2], [2,3], [3,4], [1,4], [1,5]] Output: [1,4] Explanation: The given undirected graph will be like this: 5 - 1 - 2 | | 4 - 3
Note:
Update (2017-09-26):
We have overhauled the problem description + test cases and specified clearly the graph is an undirected graph. For the directedgraph follow
up please see Redundant Connection II). We apologize
for any inconvenience caused.
簡要題解:
使用並查集這個數據結構。用一個樹結構來存儲一個原圖中的連通分量中包含的所有結點。樹中的每個結點包含兩個信息,一個是父指針parent(根結點的父指針指向自己),另一個是其子樹的高度rank。合併兩個樹時,用rank值較小的那個根的父指針指向另一個根,使得樹的高度儘量底。rank值都一樣時就隨意。
初始時,原圖中的每一個結點代表一個連通分量,並以此來構造樹(每個樹僅包含一個結點)。然後,通過按前後順序遍歷各個邊,對一條邊的兩個端點所在的兩個連通分量進行合併。一旦發現某條邊的兩個端點都在同一個連通分量中,就合併失敗,並返回這個邊。(注意: 所得的邊就是後出現的那個,因爲較早出現的邊已經成功併入連通分量中才會導致後出現的那個邊加入後會出現一個環)
代碼:
class Solution {
private:
int* parent;
int* rank;
public:
int find(int x) {
while (x != parent[x])
x = parent[x];
return x;
}
bool union(int x, int y) {
int xr = find(x);
int yr = find(y);
if (xr == yr) {
return false;
} else if (rank[xr] < rank[yr]) {
parent[xr] = yr;
} else if (rank[xr] > rank[yr]) {
parent[yr] = xr;
} else {
parent[yr] = xr;
rank[xr]++;
}
return true;
}
vector<int> findRedundantConnection(vector<vector<int> >& edges) {
parent = new int[1024];
for (int i = 0; i < 1024; i++)
parent[i] = i;
rank = new int[1024];
for (int i = 0; i < edges.size(); i++)
if (!union(edges[i][0], edges[i][1]))
return edges[i];
}
};