zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    android实现点击短链接进入应用 并获得整个连接的内容
    机房收费系统=三层+设计模式
    【数据库】SQL优化方法汇总
    HBase 数据库检索性能优化策略--转
    How to fix “HTTP Status Code 505 – HTTP Version Not Supported” error?--转
    使用VBS控制声音
    MSG命令使用详解
    bat删除系统默认共享
    C#:消息队列应用程序
    读写XML文档时,去掉新增加节点的“空命名空间”(xmlns=””)
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13463527.html
Copyright © 2011-2022 走看看