A typical Union-Find one. I‘m using a kinda Union-Find solution here. Some boiler-plate code - yeah I know.
class Solution { unordered_set<int> hs; // start from 1 int max_k; public: void dfs(vector<vector<int>> &mt, int x, int y, int f) { int n = mt.size(), m = mt[0].size(); mt[y][x] = f; if(x > 0 && mt[y][x - 1] != f && mt[y][x - 1] != 0) // left { mt[y][x - 1] = f; dfs(mt, x - 1, y, f); } if(x < m - 1 && mt[y][x + 1] != f && mt[y][x + 1] != 0) // right { mt[y][x + 1] = f; dfs(mt, x + 1, y, f); } if(y > 0 && mt[y - 1][x] != f && mt[y - 1][x] != 0) // up { mt[y - 1][x] = f; dfs(mt, x, y - 1, f); } if(y < n - 1 && mt[y + 1][x] != f && mt[y + 1][x] != 0) // down { mt[y + 1][x] = f; dfs(mt, x, y + 1, f); } } void update(vector<vector<int>> &mt, Point &p) { int n = mt.size(), m = mt[0].size(); int minf = INT_MAX; vector<Point> to_union; if(p.x > 0) // left { if(mt[p.y][p.x - 1] != 0) { minf = min(minf, mt[p.y][p.x - 1]); to_union.push_back(Point(p.x - 1, p.y)); } } if(p.x < m - 1) // right { if(mt[p.y][p.x + 1] != 0) { minf = min(minf, mt[p.y][p.x + 1]); to_union.push_back(Point(p.x + 1, p.y)); } } if(p.y > 0) // update { if(mt[p.y - 1][p.x] != 0) { minf = min(minf, mt[p.y - 1][p.x]); to_union.push_back(Point(p.x, p.y - 1)); } } if(p.y < n - 1) // down { if(mt[p.y + 1][p.x] != 0) { minf = min(minf, mt[p.y + 1][p.x]); to_union.push_back(Point(p.x, p.y + 1)); } } //// if(minf == INT_MAX) { int np = max_k ++; mt[p.y][p.x] = np; hs.insert(np); } else { mt[p.y][p.x] = minf; for(auto &tp:to_union) { if(mt[tp.y][tp.x] != 0 && mt[tp.y][tp.x] != minf) { int old = mt[tp.y][tp.x]; dfs(mt, tp.x, tp.y, minf); hs.erase(old); } } } } /** * @param n an integer * @param m an integer * @param operators an array of point * @return an integer array */ vector<int> numIslands2(int n, int m, vector<Point>& operators){ vector<vector<int>> mt(m, vector<int>(n)); max_k = 1; vector<int> ret; for(auto &p : operators) { update(mt, p); ret.push_back(hs.size()); } return ret; } };
时间: 2024-10-29 17:04:57