// 128. Longest Consecutive Sequence // A small tweak on UnionFind to add the FindSize method for this problem public int LongestConsecutive(int[] nums) { var uf = new UnionFind(nums.Length); var dict = new Dictionary <int, int>(); var maxLength = 0; for (int i = 0; i < nums.Length; i++) { if (!dict.ContainsKey(nums[i])) { dict.Add(nums[i], i); } else { continue; } if (dict.ContainsKey(nums[i] - 1)) { uf.Union(i, dict[nums[i] - 1]); } if (dict.ContainsKey(nums[i] + 1)) { uf.Union(i, dict[nums[i] + 1]); } maxLength = Math.Max(maxLength, uf.FindSize(i)); } return(maxLength); }
// 695. Max Area of Island public int MaxAreaOfIsland(int[][] grid) { var m = grid.Length; var n = grid[0].Length; var totalLength = m * n; var uf = new UnionFind(totalLength + 1); var maxArea = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 0) { uf.Union(i * n + j, totalLength); } else { if (j + 1 < n && grid[i][j + 1] == 1) { uf.Union(i * n + j, i * n + j + 1); } if (i + 1 < m && grid[i + 1][j] == 1) { uf.Union((i + 1) * n + j, i * n + j); } maxArea = Math.Max(maxArea, uf.FindSize(i * n + j)); } } } return(maxArea); }
// Union Find solution // great solution public int NumIslands2(char[][] grid) { var m = grid.Length; var n = grid[0].Length; var totalLength = m * n; var uf = new UnionFind(totalLength + 1); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == '1') { if (j + 1 < n && grid[i][j + 1] == '1') { uf.Union(i * n + j, i * n + j + 1); } if (i + 1 < m && grid[i + 1][j] == '1') { uf.Union(i * n + j, (i + 1) * n + j); } } else { uf.Union(i * n + j, totalLength); } } } return(uf.Count() - 1); }
public int CalculateEnclosedArea(int[][] grid) { var m = grid.Length; var n = grid[0].Length; var totalCells = m * n; var uf = new UnionFind(totalCells + 3); // uf[totalCells] -> 0 cell that is not enclosed, // uf[totalCells + 1] -> wall cells(value >= 1), // uf[totalCells + 2] -> enclosed 0 cells for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] > 0) { uf.Union(i * n + j, totalCells + 1); } if (grid[i][j] == 0) { if (i == 0 || j == 0 || i == m - 1 || j == n - 1) { uf.Union(i * n + j, totalCells); } if (i + 1 < m && grid[i + 1][j] == 0) { uf.Union(i * n + j, (i + 1) * n + j); } if (j + 1 < n && grid[i][j + 1] == 0) { uf.Union(i * n + j, i * n + j + 1); } } } } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 0 && !uf.Connected(i * n + j, totalCells)) { uf.Union(i * n + j, totalCells + 2); } } } return(uf.FindSize(totalCells + 2) - 1); }
// 261. Graph Valid Tree // Ridiculously easy with UnionFind public bool ValidTree(int n, int[][] edges) { var uf = new UnionFind(n); foreach (var e in edges) { if (uf.Connected(e[0], e[1])) { return(false); } uf.Union(e[0], e[1]); } return(uf.Count() == 1); }
// 990. Satisfiability of Equality Equations // This solution is super easy and mathmatically brilliant with the usage of Union-Find public bool EquationsPossible(string[] equations) { var uf = new UnionFind(26); foreach (var eq in equations) { if (eq.Substring(1, 2) == "==") { uf.Union(eq[0] - 'a', eq[3] - 'a'); } } foreach (var eq in equations) { if (eq.Substring(1, 2) == "!=") { if (uf.Connected(eq[0] - 'a', eq[3] - 'a')) { return(false); } } } return(true); }
// 130. Surrounded Regions // This solution with Union-find, very hard-core algorithm public void Solve(char[][] board) { var m = board.Length; var n = board[0].Length; var totalLength = m * n; var uf = new UnionFind(totalLength + 1); // one extra cell for initial connectivity // input perimeter cells for (int i = 0; i < n; i++) { if (board[0][i] == 'O') { uf.Union(i, totalLength); } if (board[m - 1][i] == 'O') { uf.Union((m - 1) * n + i, totalLength); } } for (int j = 0; j < m; j++) { if (board[j][0] == 'O') { uf.Union(j * n, totalLength); } if (board[j][n - 1] == 'O') { uf.Union(j * n + n - 1, totalLength); } } for (int x = 0; x < m; x++) { for (int y = 0; y < n; y++) { if (board[x][y] != 'O') { continue; } if (x - 1 >= 0 && board[x - 1][y] == 'O') { uf.Union(x * n + y, (x - 1) * n + y); } if (x + 1 < m && board[x + 1][y] == 'O') { uf.Union(x * n + y, (x + 1) * n + y); } if (y - 1 >= 0 && board[x][y - 1] == 'O') { uf.Union(x * n + y, x * n + y - 1); } if (y + 1 < n && board[x][y + 1] == 'O') { uf.Union(x * n + y, x * n + y + 1); } } } for (int x = 1; x < m - 1; x++) { for (int y = 1; y < n - 1; y++) { if (board[x][y] == 'O' && !uf.Connected(x * n + y, totalLength)) { board[x][y] = 'X'; } } } }