class Solution:
def removeStones(self, stones: List[List[int]]) -> int:
if len(stones)==1 or len(stones)==0:
return 0
#移除的石子数量=图中点个数-极大连通分量数
#建图也比较有意思,如果他两的横坐标或者纵坐标相同,那么他俩之间就有一条边存在
n = len(stones)
edge = collections.defaultdict(list)
for i, (x1, y1) in enumerate(stones):
for j, (x2, y2) in enumerate(stones):
if x1 == x2 or y1 == y2:
edge[i].append(j)
#对图进行DFS遍历,将刚才已经访问过的节点添加到集合中去
#然后遍历整个节点所连的其余节点,如果不在已经访问过的集合中,那就继续递归访问
def dfs(x):
vis.add(x)
for y in edge[x]:
if y not in vis:
dfs(y)
#设置一个集合,记录访问过的元素
#遍历图中的每一个点,如果该点不在集合中,那么就加1,然后递归遍历
vis = set()
num = 0
for i in range(n):
if i not in vis:
num += 1
dfs(i)
return n - num
- 把题目看作是一个图的问题
- 如果两个点的横坐标或者纵坐标相同的话那么就认为这两个点之间存在边,然后构造出一个图来
- 然后去遍历整个图,寻找该图的最大连通分量
- 最终移除的个数=图中点的个数-最大连通分量个数
总结:在处理图的问题中,构图十分重要,有时候根据不同的问题构图的标准也是不一样的。最大连通分量的概念就是如果在添加图中一个点,这个连通分量构成的子图就不连通了。