1. 程式人生 > 實用技巧 >947. Most Stones Removed with Same Row or Column

947. Most Stones Removed with Same Row or Column

問題:

在座標系中,給定一組座標點。

我們假設,可以刪除一個點,若存在與該點,x座標相同or y座標相同的其他點。

刪除動作連續進行,最多可以有多少次刪除動作?

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

解法:並查集(Disjoint Set)

由本題題意可知:

擁有相同x座標 or y座標的點,可以進行刪除動作。

我們將這些點連為一個組,從邊緣開始刪除,即可使刪除動作最多,為point總數-1,最後留下一個點。

那麼每個聯通組,最後都剩下一個點,

總共的刪除動作則為,總點數-聯通組個數

連通圖問題,仍使用 並查集 來求解。

對每一個點,去判斷已遍歷過的點,是否與自己聯通,若聯通,則merge

最後計算聯通組個數。

程式碼參考:

 1 class Solution {
 2 public:
 3     int removeStones(vector<vector<int
>>& stones) { 4 DisjointSet DS(stones.size()); 5 for(int i=1; i<stones.size(); i++) { 6 for(int j=0; j<i; j++) { 7 if(stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1]) { 8 DS.merge(i,j); 9 }
10 } 11 } 12 //each group may leave 1 point, number of moves is sum(group point)-1 13 //move from leaf node. can make number of moves lagger. 14 return stones.size()-DS.getGroupCount(); 15 } 16 };

並查集 程式碼參考:

 1 class DisjointSet {
 2 public:
 3     DisjointSet(int n):root(n,0), rank(n,0) {
 4         for(int i=0; i<n; i++) {
 5             root[i] = i;
 6         }
 7     }
 8     int find(int i) {
 9         if(i!=root[i]) {
10             root[i] = find(root[i]);
11         }
12         return root[i];
13     }
14     bool merge(int x, int y) {
15         int x_root = find(x);
16         int y_root = find(y);
17         if(x_root == y_root) return false;
18         if(rank[x_root] > rank[y_root]) {
19             root[y_root] = x_root;
20         } else if(rank[y_root] > rank[x_root]) {
21             root[x_root] = y_root;
22         } else {
23             root[x_root] = y_root;
24             rank[y_root] ++;
25         }
26         return true;
27     }
28     int getGroupCount() {
29         int res=0;
30         for(int i=0; i<root.size(); i++) {
31             if(i==root[i]) res++;
32         }
33         return res;
34     }
35 private:
36     vector<int> root;
37     vector<int> rank;
38 };