Skip to content

Instantly share code, notes, and snippets.

@sharunkumar
Last active February 8, 2023 22:24
Show Gist options
  • Save sharunkumar/9eb3b51284ae2e2dcfe077c5520cd634 to your computer and use it in GitHub Desktop.
Save sharunkumar/9eb3b51284ae2e2dcfe077c5520cd634 to your computer and use it in GitHub Desktop.
Union-Find
class UnionFind {
private int[] root;
private int[] rank;
public UnionFind(int n) {
this.root = new int[n];
this.rank = new int[n];
for (int i = 0; i < n; ++i) {
this.root[i] = i;
this.rank[i] = 1;
}
}
public int find(int x) {
if (this.root[x] != x) {
this.root[x] = find(this.root[x]);
}
return this.root[x];
}
public void union(int x, int y) {
int rootX = find(x), rootY = find(y);
if (rootX != rootY) {
if (this.rank[rootX] > this.rank[rootY]) {
int tmp = rootX;
rootX = rootY;
rootY = tmp;
}
// Modify the root of the smaller group as the root of the
// larger group, also increment the size of the larger group.
this.root[rootX] = rootY;
this.rank[rootY] += this.rank[rootX];
}
}
}
class Solution {
public boolean validPath(int n, int[][] edges, int source, int destination) {
UnionFind uf = new UnionFind(n);
for (int[] edge : edges) {
uf.union(edge[0], edge[1]);
}
return uf.find(source) == uf.find(destination);
}
}
class UnionFind {
HashMap<Integer, Integer> parent;
HashMap<Integer, Integer> rank;
UnionFind() {
parent = new HashMap<>();
rank = new HashMap<>();
}
int find(int x) {
if (!parent.containsKey(x)) {
parent.put(x, x);
rank.put(x, 1);
return x;
}
if (parent.get(x) != x) {
parent.put(x, find(parent.get(x)));
}
return parent.get(x);
}
void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY) {
return;
}
if (rank.get(rootX) < rank.get(rootY)) {
parent.put(rootX, rootY);
rank.put(rootY, rank.get(rootY) + rank.get(rootX));
} else {
parent.put(rootY, rootX);
rank.put(rootX, rank.get(rootX) + rank.get(rootY));
}
}
}
class Solution {
public int longestConsecutive(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
UnionFind uf = new UnionFind();
for (int num : nums) {
if (uf.parent.containsKey(num)) {
continue;
}
if (uf.parent.containsKey(num - 1)) {
uf.union(num, num - 1);
}
if (uf.parent.containsKey(num + 1)) {
uf.union(num, num + 1);
}
}
int maxLength = 0;
for (int root : uf.parent.keySet()) {
int length = uf.rank.get(uf.find(root));
maxLength = Math.max(maxLength, length);
}
return maxLength;
}
}
public class Solution {
private int find(int[] representative, int vertex) {
if (vertex == representative[vertex]) {
return vertex;
}
return representative[vertex] = find(representative, representative[vertex]);
}
private int combine(int[] representative, int[] size, int vertex1, int vertex2) {
vertex1 = find(representative, vertex1);
vertex2 = find(representative, vertex2);
if (vertex1 == vertex2) {
return 0;
} else {
if (size[vertex1] > size[vertex2]) {
size[vertex1] += size[vertex2];
representative[vertex2] = vertex1;
} else {
size[vertex2] += size[vertex1];
representative[vertex1] = vertex2;
}
return 1;
}
}
public int countComponents(int n, int[][] edges) {
int[] representative = new int[n];
int[] size = new int[n];
for (int i = 0; i < n; i++) {
representative[i] = i;
size[i] = 1;
}
int components = n;
for (int i = 0; i < edges.length; i++) {
components -= combine(representative, size, edges[i][0], edges[i][1]);
}
return components;
}
}
class UnionFind {
int count; // # of connected components
int[] parent;
int[] rank;
public UnionFind(char[][] grid) { // for problem 200
count = 0;
int m = grid.length;
int n = grid[0].length;
parent = new int[m * n];
rank = new int[m * n];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == '1') {
parent[i * n + j] = i * n + j;
++count;
}
rank[i * n + j] = 0;
}
}
}
public int find(int i) { // path compression
if (parent[i] != i) parent[i] = find(parent[i]);
return parent[i];
}
public void union(int x, int y) { // union with rank
int rootx = find(x);
int rooty = find(y);
if (rootx != rooty) {
if (rank[rootx] > rank[rooty]) {
parent[rooty] = rootx;
} else if (rank[rootx] < rank[rooty]) {
parent[rootx] = rooty;
} else {
parent[rooty] = rootx; rank[rootx] += 1;
}
--count;
}
}
public int getCount() {
return count;
}
}
class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int nr = grid.length;
int nc = grid[0].length;
int num_islands = 0;
UnionFind uf = new UnionFind(grid);
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
grid[r][c] = '0';
if (r - 1 >= 0 && grid[r-1][c] == '1') {
uf.union(r * nc + c, (r-1) * nc + c);
}
if (r + 1 < nr && grid[r+1][c] == '1') {
uf.union(r * nc + c, (r+1) * nc + c);
}
if (c - 1 >= 0 && grid[r][c-1] == '1') {
uf.union(r * nc + c, r * nc + c - 1);
}
if (c + 1 < nc && grid[r][c+1] == '1') {
uf.union(r * nc + c, r * nc + c + 1);
}
}
}
}
return uf.getCount();
}
}
class UnionFind {
int[] parent;
int[] rank;
public UnionFind(int size) {
parent = new int[size];
for (int i = 0; i < size; i++)
parent[i] = i;
rank = new int[size];
}
public int find(int x) {
if (parent[x] != x)
parent[x] = find(parent[x]);
return parent[x];
}
public void union(int x, int y) {
int xset = find(x), yset = find(y);
if (xset == yset) {
return;
} else if (rank[xset] < rank[yset]) {
parent[xset] = yset;
} else if (rank[xset] > rank[yset]) {
parent[yset] = xset;
} else {
parent[yset] = xset;
rank[xset]++;
}
}
}
class Solution {
public boolean possibleBipartition(int n, int[][] dislikes) {
Map<Integer, List<Integer>> adj = new HashMap<>();
for (int[] edge : dislikes) {
int a = edge[0], b = edge[1];
adj.computeIfAbsent(a, value -> new ArrayList<Integer>()).add(b);
adj.computeIfAbsent(b, value -> new ArrayList<Integer>()).add(a);
}
UnionFind dsu = new UnionFind(n + 1);
for (int node = 1; node <= n; node++) {
if (!adj.containsKey(node))
continue;
for (int neighbor : adj.get(node)) {
// Check if the node and its neighbor is in the same set.
if (dsu.find(node) == dsu.find(neighbor))
return false;
// Move all the neighbours into same set as the first neighbour.
dsu.union(adj.get(node).get(0), neighbor);
}
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment