publicintlongestConsecutive(int[] nums){ Map<Integer, Integer> m = new HashMap<>(); int N = nums.length; if (N < 2) return N; union_find uf = new union_find(N); for (int i = 0; i < N; i++) { if (m.containsKey(nums[i])) continue; if (m.containsKey(nums[i] - 1)) uf.union(i, m.get(nums[i] - 1)); if (m.containsKey(nums[i] + 1)) uf.union(i, m.get(nums[i] + 1)); m.put(nums[i], i); } return uf.GetMax(); }
classSolution{ publicintlongestConsecutive(int[] nums){ Map<Integer, Integer> m = new HashMap<>(); int N = nums.length; if (N < 2) return N; union_find uf = new union_find(N); for (int i = 0; i < N; i++) { if (m.containsKey(nums[i])) continue; if (m.containsKey(nums[i] - 1)) uf.union(i, m.get(nums[i] - 1)); if (m.containsKey(nums[i] + 1)) uf.union(i, m.get(nums[i] + 1)); m.put(nums[i], i); } return uf.GetMax(); } }
classunion_find{ privateint[] id; privateint[] sz; privateint M = 1; publicunion_find(int N){ id = newint[N]; sz = newint[N]; for (int i = 0; i < N; i++) { id[i] = i; sz[i] = 1; } } publicbooleanconnected(int p, int q){ return find(p) == find(q); } publicintfind(int p){ int tmp = p; while (p != id[p]) p = id[p]; while (tmp != id[tmp]) { int t = tmp; tmp = id[tmp]; id[t] = p; } return p; } publicvoidunion(int p, int q){ int pRoot = find(p); int qRoot = find(q); if (sz[pRoot] < sz[qRoot]) { id[pRoot] = qRoot; sz[qRoot] += sz[pRoot]; M = Math.max(M, sz[qRoot]); } else { id[qRoot] = pRoot; sz[pRoot] += sz[qRoot]; M = Math.max(M, sz[pRoot]); } } publicintGetMax(){ return M; } }
classSolution: deflongestConsecutive(self, nums: List[int]) -> int: d = {} N = len(nums) if N < 2: return N qu = quick_union(N) for i inrange(N): if nums[i] in d.keys(): continue if nums[i] - 1in d.keys(): qu.union(i, d[nums[i] - 1]) if nums[i] + 1in d.keys(): qu.union(i, d[nums[i] + 1]) d[nums[i]] = i return qu.GetMax()
int len = board.length; // 矩阵行数 int wid = board[0].length; // 矩阵列数,即第一行元素数 int boardSize = len * wid; // 矩阵大小(元素个数) union_find uf = new union_find(boardSize + 1); // 初始化并查集,大小为矩阵大小+1
classSolution{ intConvert(int x, int y, int w){ //x、y 表示二维坐标值,w 表示矩阵宽度。 return x * w + y; } publicvoidsolve(char[][] board){ int len = board.length; // 矩阵行数 int wid = board[0].length; // 矩阵列数,即第一行元素数 int boardSize = len * wid; // 矩阵大小(元素个数) union_find uf = new union_find(boardSize + 1); // 初始化并查集,大小为矩阵大小+1
for (int i = 0; i < len; i++) { for (int j = 0; j < wid; ) { if (board[i][j] == 'O') uf.union(Convert(i, j, wid), boardSize); // 当元素为 O 时将其与“祖宗节点”相连 if (i == 0 || i == len - 1 || j != 0) j++; else j = wid - 1; // 当不在首尾行且位于行首时,直接跳到行尾 } }
/* * 有趣的是,本段程序原本并没有在创建新连接之前判断两节点是否 * 已经相连,而且运行时也并没有报错,但是在用 c++ 实现的过程 * 中就发现 sz[] 数组爆栈了,原因就是重复创建连接会导致 sz[] * 数组中的值翻倍。 * 然而这实际上应该在 union() 函数中完成,当时我觉得 union() * 函数的调用应该基于不相连,事实证明,永远不要让函数的实现基 * 于信任! * 本程序选择在 if 中进行判断,对并查集的修改于 Python 与 * c++ 中展示。 */ for (int i = 1; i < len - 1; i++) { for (int j = 1; j < wid - 1; j++) { // i、j 均跳过首尾,从而跳过边界 if (board[i][j] == 'O') { int index = Convert(i, j, wid); if (board[i - 1][j] == 'O' && !uf.connected(Convert(i - 1, j, wid), index)) uf.union(Convert(i - 1, j, wid), index); if (board[i + 1][j] == 'O' && !uf.connected(Convert(i + 1, j, wid), index)) uf.union(Convert(i + 1, j, wid), index); if (board[i][j + 1] == 'O' && !uf.connected(Convert(i, j + 1, wid), index)) uf.union(Convert(i, j + 1, wid), index); if (board[i][j - 1] == 'O' && !uf.connected(Convert(i, j - 1, wid), index)) uf.union(Convert(i, j - 1, wid), index); } } }
for (int i = 1; i < len - 1; i++) { for (int j = 1; j < wid - 1; j++) { if (board[i][j] == 'O' && !uf.connected(Convert(i, j, wid), boardSize)) board[i][j] = 'X'; } } } }
publicclassunion_find{ privateint[] id; privateint[] sz; publicunion_find(int N){ id = newint[N]; sz = newint[N]; for (int i = 0; i < N; i++) { id[i] = i; sz[i] = 1; } } publicbooleanconnected(int p, int q){ return find(p) == find(q); } publicintfind(int p){ int tmp = p; while (p != id[p]) p = id[p]; while (tmp != id[tmp]) { int t = tmp; tmp = id[tmp]; id[t] = p; } return p; } publicvoidunion(int p, int q){ int pRoot = find(p); int qRoot = find(q); if (sz[pRoot] < sz[qRoot]) { id[pRoot] = qRoot; sz[qRoot] += sz[pRoot]; } else { id[qRoot] = pRoot; sz[pRoot] += sz[pRoot]; } } }