947. Most Stones Removed with Same Row or Column
阿新 • • 發佈:2020-08-09
問題:
在座標系中,給定一組座標點。
我們假設,可以刪除一個點,若存在與該點,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 };