链接:https://leetcode.com/tag/union-find/
【128】Longest Consecutive Sequence (2018年11月22日,开始解决hard题)
给了一个无序的数组,问这个数组里面的元素(可以重新排序)能组成的最长的连续子序列是多长。本题的时间复杂度要求是 O(N).
本题 array 专题里面有, 链接:https://www.cnblogs.com/zhangwanying/p/9610923.html ,用个 hashmap 可以做到 O(N).
本题用 union-find 怎么解,不知道 orz。
【130】Surrounded Regions (2019年1月31日,UF专题)
给了个二维 grid,把里面 O 全部变成 X,但是 边界和边界联通区域内的 O 保留。
题解:我以前是用dfs解的。今天看了discuss高票使用UF,学习了一下。我们把边界上的 O 和边界联通区域内的 O 的坐标与一个 dummy node 联通就好了。然后遍历 grid,如果坐标与 dummy node 坐标联通,就保留成 O,不然改成 X
1 class UF { 2 public: 3 UF(int size) { 4 father.resize(size); 5 rank.resize(size, 0); 6 for (int i = 0; i < size; ++i) { 7 father[i] = i; 8 } 9 } 10 int find(int x) { 11 return x == father[x] ? x : father[x] = find(father[x]); 12 } 13 void connect(int x, int y) { 14 int xx = find(x), yy = find(y); 15 if (xx == yy) { return; } 16 if (yy > xx) { 17 father[xx] = yy; 18 } else { 19 father[yy] = x; 20 } 21 } 22 vector<int> father; 23 vector<int> rank; 24 }; 25 class Solution { 26 public: 27 void solve(vector<vector<char>>& board) { 28 if (board.empty() || board[0].empty()) { return; } 29 const int n = board.size(), m = board[0].size(); 30 UF uf(n * m + 1); 31 for (int i = 0; i < n; ++i) { 32 for (int j = 0; j < m; ++j) { 33 if (board[i][j] == 'O') { 34 if ((i == 0 || i == n-1 || j == 0 || j == m-1)) { 35 uf.connect(i * m + j, n * m); 36 } else { 37 if (board[i-1][j] == 'O') { 38 uf.connect(i * m + j, (i-1) * m + j); 39 } 40 if (board[i+1][j] == 'O') { 41 uf.connect(i * m + j, (i+1) * m + j); 42 } 43 if (board[i][j-1] == 'O') { 44 uf.connect(i * m + j, i * m + j - 1); 45 } 46 if (board[i][j+1] == 'O') { 47 uf.connect(i * m + j, i * m + j + 1); 48 } 49 } 50 } 51 } 52 } 53 for (int i = 0; i < n; ++i) { 54 for (int j = 0; j < m; ++j) { 55 if (uf.find(i * m +j) != n * m) { 56 board[i][j] = 'X'; 57 } 58 } 59 } 60 return; 61 } 62 };