路飞]_leetcode-947-移除最多的同行或同列石头

简介: leetcode-947-移除最多的同行或同列石头

网络异常,图片无法展示
|


[题目地址][B站地址]


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

如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。


给你一个长度为 n 的数组 stones ,其中 stones[i] = [xi, yi] 表示第 i 块石头的位置,返回 可以移除的石子 的最大数量。


示例 1:


输入: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
输出: 5
解释: 一种移除 5 块石头的方法如下所示:
1. 移除石头 [2,2] ,因为它和 [2,1] 同行。
2. 移除石头 [2,1] ,因为它和 [0,1] 同列。
3. 移除石头 [1,2] ,因为它和 [1,0] 同行。
4. 移除石头 [1,0] ,因为它和 [0,0] 同列。
5. 移除石头 [0,1] ,因为它和 [0,0] 同行。
石头 [0,0] 不能移除,因为它没有与另一块石头同行/列。
复制代码


示例 2:


输入: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
输出: 3
解释: 一种移除 3 块石头的方法如下所示:
1. 移除石头 [2,2] ,因为它和 [2,0] 同行。
2. 移除石头 [2,0] ,因为它和 [0,0] 同列。
3. 移除石头 [0,2] ,因为它和 [0,0] 同行。
石头 [0,0] 和 [1,1] 不能移除,因为它们没有与另一块石头同行/列。
复制代码


示例 3:


输入: stones = [[0,0]]
输出: 0
解释: [0,0] 是平面上唯一一块石头,所以不可以移除它。
复制代码


提示:


  • 1 <= stones.length <= 1000
  • 0 <= xi, yi <= 104
  • 不会有两块石头放在同一个坐标点上


解题思路


本题其实就类似于消消乐游戏,当同行或同列有一个以上的石头,除了最后一个,都可以删除。


而且这个过程是可以递推的,所以我们可以把在同行或同列的石头放在一个集合,这样的一个集合中,只需要保留一块石头即可。


通过这种方式就可以获取到可移除的石头的数量。


因为过程中需要频繁对集合进行合并,以及获取石头所在集合,所以可以需要借助并查集解题。


如果你对 并查集 还不了解,可以看我这一篇文章 数据结构-并查集,文中介绍了并查集的概念、应用场景以及手写实现的全过程。


动画演示


网络异常,图片无法展示
|


代码实现


class UnionSet {
  constructor(n){
    // 初始化节点数量数组
    this.size = Array(n).fill(1);
    // 初始化集合列表,每一个节点为一个集合
    this.list = Array(n);
    for(let i = 0;i<n;i++){
      this.list[i] = i;
    }
  }
  // 递归获取元素所在集合根节点
  find(x){
    if(this.list[x] === x) return x;
    // 获取到元素所在集合根节点
    const root = this.find(this.list[x])
    // 将当前节点挂载为根节点子节点,压缩路径
    this.list[x] = root;
    return root;
  }
  // 合并两个集合
  merge(rootA,rootB){
    // 如果 a 所在集合元素数量更多,将 b 所在集合合并到 a 所在集合
    if(this.size[rootA]>this.size[rootB]){
      this.list[rootB] = rootA;
      this.size[rootA] += this.size[rootB]
    }else{
      // 反之将 a 所在集合合并到 b 所在集合
      this.list[rootA] = rootB;
      this.size[rootB] += this.size[rootA]
    }
  }
}
var removeStones = function(stones) {
  // 获取石头数量
  const len = stones.length,
  // 创建并查集实例
  unionset = new UnionSet(len);
  // 初始化结果值
  let res = 0;
  for(let i = 0;i<len-1;i++){
    for(let j = i+1;j<len;j++){
      if(stones[i][0]===stones[j][0]||stones[i][1]===stones[j][1]){
        // 获取两个元素所在集合的根节点
        const rootA = unionset.find(i),rootB = unionset.find(j)
        // 如果两个根节点不同,则进行合并,同时一次合并可以看做删除一个石头,结果值+1
        if(rootA!==rootB){
          res++;
          unionset.merge(rootA,rootB)
        }
      }
    }
  }
  // 返回结果值
  return res;
};
复制代码


至此我们就完成了 leetcode-947-移除最多的同行或同列石头


如有任何问题或建议,欢迎留言讨论!

相关文章
【Leetcode -766.托普利茨矩阵 -771.宝石与石头】
【Leetcode -766.托普利茨矩阵 -771.宝石与石头】
55 0
|
3月前
|
Python
【Leetcode刷题Python】1049. 最后一块石头的重量 II
LeetCode 1049题 "最后一块石头的重量 II" 的Python解决方案,通过动态规划算法计算使最后一块石头的重量最小的方案。
37 1
|
5月前
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
|
6月前
代码随想录Day36 动态规划05 LeetCode T1049最后一块石头的重量II T494 目标和 T474 一和零
代码随想录Day36 动态规划05 LeetCode T1049最后一块石头的重量II T494 目标和 T474 一和零
58 0
|
6月前
|
Java
leetcode-1049. 最后一块石头的重量 II
leetcode-1049. 最后一块石头的重量 II
52 0
|
算法 测试技术 容器
代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
46 1
leetcode 1049 最后一块石头的重量
leetcode 1049 最后一块石头的重量
93 0
leetcode 1049 最后一块石头的重量
力扣刷题记录——709. 转换成小写字母、771. 宝石与石头、704. 二分查找
力扣刷题记录——709. 转换成小写字母、771. 宝石与石头、704. 二分查找
111 0
力扣刷题记录——709. 转换成小写字母、771. 宝石与石头、704. 二分查找
LeetCode 771. 宝石与石头
给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。
105 0
|
前端开发 算法 JavaScript
LeetCode宝石与石头使用JavaScript解题|前端学算法
LeetCode宝石与石头使用JavaScript解题|前端学算法
107 0
LeetCode宝石与石头使用JavaScript解题|前端学算法