website/content.en/ChapterFour/0900~0999/0947.Most-Stones-Removed-with-Same-Row-or-Column.md
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 <= 10000 <= stones[i][j] < 10000On a 2D plane, we place stones at some integer coordinate points. Each coordinate point may have at most one stone. Now, a move operation removes a stone that shares a column or row with another stone on the grid. What is the maximum number of move operations we can perform?
Hint:
union() all points that share the same row or column. Points in different sets cannot remove each other. Proof by contradiction: if they can be removed, it means there exists a same-row or same-column situation, so they must be in the same set, which contradicts being in different sets. The points left in the end are the number of sets, and each set will leave only one point. So the number of removed points is the total number of points minus the number of sets: len(stones) - uf.totalCount().
package leetcode
import (
"github.com/halfrost/leetcode-go/template"
)
func removeStones(stones [][]int) int {
if len(stones) <= 1 {
return 0
}
uf, rowMap, colMap := template.UnionFind{}, map[int]int{}, map[int]int{}
uf.Init(len(stones))
for i := 0; i < len(stones); i++ {
if _, ok := rowMap[stones[i][0]]; ok {
uf.Union(rowMap[stones[i][0]], i)
} else {
rowMap[stones[i][0]] = i
}
if _, ok := colMap[stones[i][1]]; ok {
uf.Union(colMap[stones[i][1]], i)
} else {
colMap[stones[i][1]] = i
}
}
return len(stones) - uf.TotalCount()
}