JAVA程序设计:移除最多的同行或同列石头(LeetCode:947)

我们将石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。

每次 move 操作都会移除一块所在行或者列上有其他石头存在的石头。

请你设计一个算法,计算最多能执行多少次 move 操作?

 

示例 1:

输入:stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
输出:5
示例 2:

输入:stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
输出:3
示例 3:

输入:stones = [[0,0]]
输出:0
 

提示:

1 <= stones.length <= 1000
0 <= stones[i][j] < 10000

思路:这道题我采用的方法是这样的,我们知道处于同一条水平直线上的点假如说有n个,那么这条线上的点肯定至少有n-1个是一定可以移除的,而剩余呢一个能不能移除是要看其他高度上的水平线上是否有一点和这个点的纵坐标一样。我觉得你能想到这里,这道问题就已经解决了。我们可以定义这样一种关系:若两条不同高度的水平直线投影到x轴上互相有重叠的部分(无缝衔接也算),那么我们说他们俩是处于同一个集合的。而最后的答案就一定是总的点数减去集合的数量。对于集合的合并,我们可以考虑并查集。

class Solution {
	
	private int[] f;
	
    public int removeStones(int[][] stones) {

    	int ans=0;
    	f=new int[10005];
    	int n=stones.length;
    	boolean[] flag=new boolean[10005];
    	
    	for(int i=0;i<10000;i++)
    		f[i]=i;

    	for(int i=0;i<n;i++) {
    		for(int j=0;j<n;j++) {
    			if(i==j || stones[i][1]!=stones[j][1])
    				continue;
    			int t1=find(stones[i][0]);
    			int t2=find(stones[j][0]);
    			if(t1!=t2)
    				f[t1]=t2;
    		}
    	}
    	
    	ans=n;
    	
    	for(int i=0;i<n;i++) {
    		if(flag[find(stones[i][0])])
    			continue;
    		ans--;
    		flag[find(stones[i][0])]=true;
    	}
    	
    	return ans;
    	
    }
    
    private int find(int x) {
    	if(f[x]==x)
    		return x;
    	return f[x]=find(f[x]);
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值