947. Most Stones Removed with Same Row or Column
On a 2D plane, we place stones at some integer coordinate points. Each coordinate point may have at most one stone.
Now, a move consists of removing a stone that shares a column or row with another stone on the grid.
What is the largest possible number of moves we can make?
Example 1:
Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
Output: 5
Example 2:
Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
Output: 3
Example 3:
Input: stones = [[0,0]]
Output: 0
Note:
1 <= stones.length <= 1000
0 <= stones[i][j] < 10000
// DFS
void dfs(vector<vector<int> >& index, unordered_set<int>& visited, int i) {
if (visited.count(i)) return;
visited.insert(i);
for (int j : index[i]) {
if (visited.count(j)) continue;
dfs(index, visited, j);
}
}
int removeStones(vector<vector<int>>& stones) {
// Trick to differentiate row id and col id
const int k = 10000;
vector<vector<int> > index(2 * k);
for (const vector<int>& stone : stones) {
index[stone[0]].push_back(stone[1] + k);
index[stone[1] + k].push_back(stone[0]);
}
unordered_set<int> visited;
int islands = 0;
for (const vector<int>& stone : stones) {
if (visited.count(stone[0])) continue;
++islands;
dfs(index, visited, stone[0]);
dfs(index, visited, stone[1] + k);
}
return stones.size() - islands;
}
// Union-Find
int find(vector<int>& roots, int i) {
return roots[i] == i ? i : roots[i] = find(roots, roots[i]);
}
void uni(vector<int>& roots, int x, int y) {
x = find(roots, x), y = find(roots, y);
if (x != y) {
roots[y] = x;
}
}
int removeStones(vector<vector<int>>& stones) {
const int k = 10000;
vector<int> roots(2 * k);
for (int i = 0; i < roots.size(); ++i) roots[i] = i;
for (const vector<int>& stone : stones) {
uni(roots, stone[0], stone[1] + k);
}
unordered_set<int> islands;
for (const vector<int>& stone : stones) {
islands.insert(find(roots, stone[0]));
}
return stones.size() - islands.size();
}
// Union-Find
int find(vector<int>& roots, int i) {
return roots[i] == i ? i : roots[i] = find(roots, roots[i]);
}
void connect(vector<int>& roots, int i, int j) {
roots[find(roots, j)] = find(roots, i);
}
int removeStones(vector<vector<int>>& stones) {
const int n = stones.size();
vector<int> roots(n);
for (int i = 0; i < n; ++i) roots[i] = i;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1]) {
connect(roots, i, j);
}
}
}
int cnt = 0;
for (int i = 0; i < n; ++i) {
if (roots[i] == i) ++cnt;
}
return n - cnt;
}
Last updated
Was this helpful?