LeetCode 947. Most Stones Removed with Same Row or Column
这道题本质就是 323. Number of Connected Components in an Undirected Graph。
DFS O(n^2)
一模一样, 只不过图要自己构建而已。
class Solution { public: vector<list<int>> adj; int removeStones(vector<vector<int>>& stones) { int n=stones.size(); adj.resize(n,list<int>()); for (int i=0;i<n;++i){ for (int j=i+1;j<n;++j){ if (stones[i][0]==stones[j][0] || stones[i][1]==stones[j][1]){ adj[i].push_back(j); adj[j].push_back(i); } } } int count=0; vector<bool> visited(n,false); for (int i=0;i<n;++i){ if (!visited[i]){ ++count; dfs(i,visited); } } return n-count; } void dfs(int i, vector<bool> &visited){ if (visited[i]) return; visited[i] = true; for (auto x:adj[i]){ dfs(x,visited); } } };
Union Find O(n^2),两两union n^2
class Solution { public: vector<int> parent; int removeStones(vector<vector<int>>& stones) { int n=stones.size(); parent.resize(n,-1); for (int i=0;i<n;++i){ for (int j=i+1;j<n;++j){ if (stones[i][0]==stones[j][0] || stones[i][1]==stones[j][1]){ Union(i,j); } } } int count=0; for (int x:parent){ if (x<0) ++count; } return n-count; } void Union(int x, int y){ // union by size int root1=Find(x), root2=Find(y); if (root1==root2) return; if (parent[root1]>parent[root2]){ parent[root2] += parent[root1]; parent[root1] = root2; }else{ parent[root1] += parent[root2]; parent[root2] = root1; } } int Find(int x){ if (parent[x]<0) return x; return parent[x]=Find(parent[x]); } };
Union Find (Optimized)
Solution里的很取巧的做法。横坐标纵坐标都一起union,这样只要遍历stones一次即可。这里将纵坐标+1000,就能简单区分横纵坐标。
时间复杂度 由于union by size,O(nlogn)。如果用union by rank来写,可以 O(n*α(n))。
class Solution { public: vector<int> parent; int removeStones(vector<vector<int>>& stones) { int n=stones.size(); parent.resize(20000,-1); for (auto stone:stones){ int x=stone[0], y=stone[1]; Union(x,y+10000); } unordered_set<int> s; for (auto stone:stones){ s.insert(Find(stone[0])); } return n-s.size(); return 0; } void Union(int x, int y){ // union by size int root1=Find(x), root2=Find(y); if (root1==root2) return; if (parent[root1]>parent[root2]){ parent[root2] += parent[root1]; parent[root1] = root2; }else{ parent[root1] += parent[root2]; parent[root2] = root1; } } int Find(int x){ if (parent[x]<0) return x; return parent[x]=Find(parent[x]); } };

浙公网安备 33010602011771号