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里面是索引下标

  • 相关阅读:
    N个数字每X个数字组成一组,求组数
    生成带文本的UIImage
    Linux创建环境变量(Mac OS)
    为UIView绘制单边的boder
    ecshop之随机文章
    微软继MVC5后,出现ASP.NET VNEXT
    本科毕业生转正之前谈待遇
    ecshop title优化
    百度地图开发之一】申请Key和配置初览显示地图
    项目总结—jQuery EasyUI-DataGrid 拼表及查看详情
  • 原文地址:https://www.cnblogs.com/jieyi/p/14284668.html
Copyright © 2011-2022 走看看