版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/84993657
在二维平面上,我们将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。
现在,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
解题思路
这个问题我拿到手首先想到的处理思路就是并查集。我们可以通过并查集很快的确定哪些元素是横坐标或者纵坐标联通(也就是确定一个集合)。我们最后的结果就是每个集合中只存放一个元素,取出其余元素。
class Solution:
def removeStones(self, stones):
"""
:type stones: List[List[int]]
:rtype: int
"""
stones = list(map(tuple, stones))
stones_len = len(stones)
uf = collections.defaultdict()
count = stones_len
for c in stones:
uf[c] = c
def find(coor):
if coor != uf[coor]:
uf[coor] = find(uf[coor])
return uf[coor]
def union(c1, c2):
nonlocal count
p1, p2 = find(c1), find(c2)
if p1 == p2:
return
uf[p1] = c2
count -= 1
for c1, c2 in itertools.combinations(stones, 2):
if c1[0] == c2[0] or c1[1] == c2[1]:
union(c1, c2)
return stones_len - count
实际上我们这个代码实现的非常不好。我们使用combinations
这个函数,这样我们的遍历次数增加了许多。我们能不能只遍历一遍就知道结果呢?我们实际上可以不通过合并点,而是通过合并x
和y
坐标实现,但是x
和y
坐标有很多相同的元素要怎么办呢?我们要知道我们通过归并点的本质其实是想要区分x
和y
坐标,所以我们在归并x
和y
坐标的时候也要将其区分,一个简单的思路就是对y
取逆。
class Solution:
def removeStones(self, stones):
"""
:type stones: List[List[int]]
:rtype: int
"""
UF = {}
def find(x):
if x != UF[x]:
UF[x] = find(UF[x])
return UF[x]
def union(x, y):
UF.setdefault(x, x)
UF.setdefault(y, y)
UF[find(x)] = find(y)
for i, j in stones:
union(i, ~j)
return len(stones) - len({find(x) for x in UF})
有了前面的思路我们不难想到这其实就是一个寻找岛屿数量的问题,通过深度优先遍历找到岛屿的个数。
from collections import defaultdict
class Solution:
def removeStones(self, stones):
"""
:type stones: List[List[int]]
:rtype: int
"""
def dfs(i, j):
visited.add((i, j))
for y in rows[i]:
if (i, y) not in visited:
dfs(i, y)
for x in cols[j]:
if (x, j) not in visited:
dfs(x, j)
visited, island, rows, cols = set(), 0, defaultdict(list), defaultdict(list)
for i, j in stones:
rows[i].append(j)
cols[j].append(i)
for i, j in stones:
if (i, j) not in visited:
dfs(i, j)
island += 1
return len(stones) - island
最后的结果就是stones
的数量减去岛屿的数量。
reference:
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!