zoukankan      html  css  js  c++  java
  • 并查集-移除最多的同行或同列石头

    /**
     * n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。
    
    如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。
    
    给你一个长度为 n 的数组 stones ,其中 stones[i] = [xi, yi] 表示第 i 块石头的位置,返回 可以移除的石子 的最大数量。
     */
    //思路,并查集
    
    
    public class test947 {
        //输入:stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]  5
        public static void main(String[] args) {
            int [][]stones={{0,0},{0,1},{1,0},{1,2},{2,1},{2,2}};
            int x=removeStones(stones);
        }
        public static int removeStones(int[][] stones) {
            if(stones.length==1){
                return 0;
            }
            int n=stones.length;
            int []parents=new int[stones.length];
            for(int i=0;i<n;i++){
                parents[i]=i;
            }
            int res=n;
            for(int i=0;i<n-1;i++){
                for(int j=i+1;j<n;j++){
                    int a=find(parents, i);
                    int b=find(parents, j);
                    if(stones[i][0]==stones[j][0]||stones[i][1]==stones[j][1]){
                        if(a!=b){
                            parents[a]=b;
                            res--;
                        }
                    }
                }
                
            }
    
            return n-res;
        }
        public static int find(int []parent,int i){
            if(parent[i]!=i){
                parent[i]=find(parent,parent[i]);
            }
            return parent[i];
        }
        
    }

    对于并查集,一般的模板是这样

    // 未改进版本
    class Djset {
    public:
        vector<int> parent;  // 记录节点的根
        Djset(int n): parent(vector<int>(n)) {
            for (int i = 0; i < n; i++) parent[i] = i;
        }
    
        int find(int x) {
            if (x != parent[x]) return find(parent[x]);
            return parent[x];
        }
    
        void merge(int x, int y) {
            int rootx = find(x);
            int rooty = find(y);
         //这个merge的地方写merge逻辑,例如对于移出同行同列石头,就是如果行或者列相同,如果a!=b,也就是之前没合并,则合并,每次合并剩下的并查集个数-1
          //对于字符串交换排序,直接merge之后,遍历所有元素,将key取出来做 map的key,value用排序队列,每次拿出来每个key的从小到大
          //对于树的冗余连接,每根边的两个端点都判断是不是在同一并查集,不是就放在一起,是就直接return
    parent[rooty]
    = rootx; } };

    要特别注意维护的parent里面是索引下标

  • 相关阅读:
    爱上你的一百个理由 (网摘)
    梦想向右,沉默向左
    明夕何夕,君已陌路。
    不肯嫁的几种男人(转)
    一剪梅
    C# preprocessor Directives
    Language
    C# Language Tour
    Web application
    Unsafe code
  • 原文地址:https://www.cnblogs.com/jieyi/p/14284668.html
Copyright © 2011-2022 走看看