LeetCode - 947 移除最多的同行或同列石头

在这里插入图片描述
在这里插入图片描述
并查集解法一

class Solution {
    Map<String,Integer> placeToIndex = new HashMap<String,Integer>();
    Map<String,List<Integer>> rcPlace = new HashMap<String,List<Integer>>();
    public int removeStones(int[][] stones) {
         int n = stones.length;
         int index = 0;
         UnionFind uf = new UnionFind(n);
         for(int i =0;i < n;i++){
             int[] stone = stones[i];
             String str = stone[0] +"," + stone[1];
             int si = index;
             placeToIndex.put(str,index++);
             String rs = "row" + stone[0];
             String cs = "col" + stone[1];
             if(rcPlace.get(rs) == null){
                 rcPlace.put(rs,new ArrayList<Integer>());
             }
             else
             {
                 List<Integer> list = rcPlace.get(rs);
                 int s = list.get(list.size()-1);
                 uf.union(s,si);
             }
             if(rcPlace.get(cs) == null){
                 rcPlace.put(cs,new ArrayList<Integer>());
             }
             else
             {
                 List<Integer> list = rcPlace.get(cs);
                 int s = list.get(list.size()-1);
                 uf.union(s,si);
             }
             rcPlace.get(rs).add(si);
             rcPlace.get(cs).add(si);
         }
         return n - uf.count;

    }
     public class UnionFind{
        int[] parent;
        int count;
        public UnionFind(int n){
            parent = new int[n];
            count = n;
            for(int i=0;i<n;i++)
               parent[i] = i;
        }
        public int find(int x){
            //路径压缩的方式
            if(parent[x] != x){
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
        public void union(int x,int y){//合并
            int rootX = find(x);
            int rootY = find(y);
            if(rootX == rootY)
               return ;
            parent[rootX] = rootY;
            count -= 1;
        }
    } 
}

并查集解法二

import java.util.HashMap;
import java.util.Map;

public class Solution {

    public int removeStones(int[][] stones) {
        UnionFind unionFind = new UnionFind();

        for (int[] stone : stones) {
            // 下面这三种写法任选其一
            // unionFind.union(~stone[0], stone[1]);
            // unionFind.union(stone[0] - 10001, stone[1]);
            unionFind.union(stone[0] + 10001, stone[1]);
        }
        return stones.length - unionFind.getCount();
    }

    private class UnionFind {

        private Map<Integer, Integer> parent;
        private int count;

        public UnionFind() {
            this.parent = new HashMap<>();
            this.count = 0;
        }

        public int getCount() {
            return count;
        }

        public int find(int x) {
            if (!parent.containsKey(x)) {
                parent.put(x, x);
                // 并查集集中新加入一个结点,结点的父亲结点是它自己,所以连通分量的总数 +1
                count++;
            }

            if (x != parent.get(x)) {
                parent.put(x, find(parent.get(x)));
            }
            return parent.get(x);
        }

        public void union(int x, int y) {
            int rootX = find(x);
            int rootY = find(y);
            if (rootX == rootY) {
                return;
            }

            parent.put(rootX, rootY);
            // 两个连通分量合并成为一个,连通分量的总数 -1
            count--;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值