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
If stone a
and stone b
are in the same column/row, we connect them as a component
The largest possible number of moves we can make = the number of unions we can make = Total stones count - count of components.
1 class Solution { 2 public int removeStones(int[][] stones) { 3 UnionFind uf = new UnionFind(stones.length); 4 int countUnion = 0; 5 for (int i = 0; i < stones.length - 1; i ++) { 6 for (int j = i + 1; j < stones.length; j ++) { 7 if (uf.isConnected(i, j)) continue; 8 if (stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1]) { 9 uf.union(i, j); 10 countUnion ++; 11 } 12 } 13 } 14 return countUnion; 15 } 16 17 public class UnionFind { 18 int[] fathers; 19 20 public UnionFind(int n) { 21 fathers = new int[n]; 22 for (int i = 0; i < n; i ++) { 23 fathers[i] = i; 24 } 25 } 26 27 public void union(int i, int j) { 28 int iRoot = find(i); 29 int jRoot = find(j); 30 fathers[jRoot] = iRoot; 31 } 32 33 public int find(int i) { 34 while (i != fathers[i]) { 35 i = fathers[i]; 36 } 37 return i; 38 } 39 40 public boolean isConnected(int i, int j) { 41 return find(i) == find(j); 42 } 43 } 44 }