// 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);
        }
예제 #2
0
        // 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);
        }
예제 #3
0
        // 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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        // 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);
        }
예제 #6
0
        // 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);
        }
예제 #7
0
        // 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';
                    }
                }
            }
        }