forked from fishercoder1534/Leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
_684.java
115 lines (100 loc) · 3.29 KB
/
_684.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package com.fishercoder.solutions;
import java.util.HashSet;
import java.util.Set;
/**
* 684. Redundant Connection
*
* We are given a "tree" in the form of a 2D-array, with distinct values for each node.
* In the given 2D-array, each element pair [u, v] represents that v is a child of u in the tree.
* We can remove exactly one redundant pair in this "tree" to make the result a (rooted) tree.
* You need to find and output such a pair. If there are multiple answers for this question, output the one appearing last in the 2D-array. There is always at least one answer.
Example 1:
Input: [[1,2], [1,3], [2,3]]
Output: [2,3]
Explanation: Original tree will be like this:
1
/ \
2 - 3
Example 2:
Input: [[1,2], [1,3], [3,1]]
Output: [3,1]
Explanation: Original tree will be like this:
1
/ \\
2 3
Note:
The size of the input 2D-array will be between 1 and 1000.
Every integer represented in the 2D-array will be between 1 and 2000.
*/
public class _684 {
public static class Solution1 {
/**
* This is my original solution. A little verbose.
*/
class UnionFind {
int[] ids;
Set<Integer> nodes;
Set<Integer> visitedNodes;
int[] redundantConn;
int m;
int n;
public UnionFind(int[][] edges) {
m = edges.length;
n = edges[0].length;
nodes = new HashSet<>();
visitedNodes = new HashSet<>();
redundantConn = new int[]{};
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
nodes.add(edges[i][j]);
}
}
ids = new int[nodes.size()];
for (int i = 0; i < ids.length; i++) {
ids[i] = i + 1;
}
}
public int[] union(int[] edge) {
int x = find(edge[0] - 1);
int y = find(edge[1] - 1);
if (x == y && visitedNodes.contains(edge[0]) && visitedNodes.contains(edge[1])) {
redundantConn = edge;
}
if (x != y) {
if (x < y) {
ids[y] = x + 1;
} else {
ids[x] = y + 1;
}
}
visitedNodes.add(edge[0]);
visitedNodes.add(edge[1]);
return redundantConn;
}
private int find(int id) {
if (isTree()) {
return ids[id];
}
if ((id + 1) != ids[id]) {
return find(ids[id] - 1);
}
return id;
}
private boolean isTree() {
Set<Integer> set = new HashSet<>();
for (int i : ids) {
set.add(i);
}
return set.size() == 1;
}
}
public int[] findRedundantConnection(int[][] edges) {
UnionFind unionFind = new UnionFind(edges);
int[] result = new int[]{};
for (int[] edge : edges) {
result = unionFind.union(edge);
}
return result;
}
}
}