예제 #1
0
        /// <summary>
        /// 目标是把周围的人都拽到自己的阵营里面
        /// </summary>
        private void Dfs(DisJointSet djs, int[][] grid, int row, int col, bool[,] visited)
        {
            if (visited[row, col])
            {
                return;
            }
            visited[row, col] = true;

            int rows = grid.Length;
            int cols = grid[0].Length;

            var upDown    = new int[] { -1, 1, 0, 0 };
            var leftRight = new int[] { 0, 0, -1, 1 };

            for (int i = 0; i < 4; i++)
            {
                var newRow = row + upDown[i];
                var newCol = col + leftRight[i];

                if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols && grid[newRow][newCol] == 1)
                {
                    Union(djs, GetIndex(row, col, cols), GetIndex(newRow, newCol, cols), rows * cols);
                    Dfs(djs, grid, newRow, newCol, visited);
                }
            }
        }
예제 #2
0
        public string SmallestStringWithSwaps(string s, IList <IList <int> > pairs)
        {
            /*
             * 题目概述:交换字符串中同组索引的元素,使得字符串的字母序最小
             *
             * 思路:
             *  1.使用并查集来将给定的索引对拼接成一个大的集体
             *  2.找到所有的集体
             *  3.将集体所代表的元素排序后写回到原来的字符串中
             *
             * 关键点:
             *  1.直接做字符串排序的话,时间复杂度较高,会超时,因为字符仅有小写字母,因此我自己写了"桶排序"来加速,效果还不错
             *
             * 时间复杂度:O(n)
             * 空间复杂度:O(n)
             */

            var DJS = new DisJointSet(s.Length);

            foreach (var pairItem in pairs)
            {
                DJS.Union(pairItem[0], pairItem[1]);
            }

            var groupDic = new Dictionary <int, IList <int> >();

            for (int i = 0; i < s.Length; i++)
            {
                var groupIndex = DJS.Find(i);

                if (!groupDic.ContainsKey(groupIndex))
                {
                    groupDic[groupIndex] = new List <int>();
                }

                groupDic[groupIndex].Add(i);
            }

            var forReturnCharArray = s.ToCharArray();

            foreach (var groupItem in groupDic)
            {
                SortedAndInsert(forReturnCharArray, groupItem.Value);
            }

            return(new string(forReturnCharArray));
        }
예제 #3
0
        private void Union(DisJointSet djs, int i, int j, int special)
        {
            var iParent = djs.Find(i);
            var jParent = djs.Find(j);

            if (iParent == special)
            {
                djs.UnionToFrom(i, j);
            }
            else if (jParent == special)
            {
                djs.UnionToFrom(j, i);
            }
            else
            {
                djs.Union(i, j);
            }
        }
예제 #4
0
        public int[] HitBricks(int[][] grid, int[][] hits)
        {
            /*
             * 题目概述:打砖块儿
             *
             * 思路:
             *  1.实现并查集,除了Union 和 Find 功能外,还需要一个获取团队人数的功能
             *  2.拷贝一份儿砖块儿,把将要打掉的砖块儿全部打掉
             *  3.然后逆序把砖块儿加上来,加上来的过程中,特定团队增加的人数,就是要求的解
             *
             * 关键点:
             *
             * 时间复杂度:
             * 空间复杂度:
             */

            int rows = grid.Length;
            int cols = grid[0].Length;

            var copyGrid = new int[grid.Length][];

            for (int r = 0; r < grid.Length; r++)
            {
                copyGrid[r] = new int[grid[r].Length];
                for (int c = 0; c < grid[r].Length; c++)
                {
                    copyGrid[r][c] = grid[r][c];
                }
            }

            for (int i = 0; i < hits.Length; i++)
            {
                var r = hits[i][0];
                var c = hits[i][1];
                copyGrid[r][c] = 0;
            }

            var djs        = new DisJointSet(rows * cols + 1);
            var visited    = new bool[rows, cols];
            var specialNum = rows * cols;

            for (int r = 0; r < copyGrid.Length; r++)
            {
                for (int c = 0; c < copyGrid[r].Length; c++)
                {
                    if (copyGrid[r][c] == 0)
                    {
                        continue;
                    }

                    if (r == 0)
                    {
                        Union(djs, specialNum, GetIndex(r, c, cols), specialNum);
                    }

                    Dfs(djs, copyGrid, r, c, visited);
                }
            }

            var forReturn = new int[hits.Length];
            var initTotal = djs.GetCount(specialNum);

            for (int i = hits.Length - 1; i >= 0; i--)
            {
                var r = hits[i][0];
                var c = hits[i][1];

                var tempValue = 0;
                if (grid[r][c] != 0)
                {
                    copyGrid[r][c] = 1;
                    if (r == 0)
                    {
                        Union(djs, specialNum, GetIndex(r, c, cols), specialNum);
                    }

                    var upDownArray    = new int[] { -1, 1, 0, 0 };
                    var leftRightArray = new int[] { 0, 0, -1, 1 };
                    for (int j = 0; j < 4; j++)
                    {
                        var newR = r + upDownArray[j];
                        var newC = c + leftRightArray[j];

                        if (newR < 0 || newR >= rows || newC < 0 || newC >= cols || copyGrid[newR][newC] != 1)
                        {
                            continue;
                        }

                        Union(djs, GetIndex(r, c, cols), GetIndex(newR, newC, cols), specialNum);
                    }

                    var temp = djs.GetCount(specialNum);
                    tempValue = temp - initTotal - 1;
                    if (tempValue < 0)
                    {
                        tempValue = 0;
                    }
                    initTotal = temp;
                }

                forReturn[i] = tempValue;
            }

            return(forReturn);
        }