0
点赞
收藏
分享

微信扫一扫

LeetCode入门计划 | 并查集(Python3)

最不爱吃鱼 2022-01-22 阅读 71

文章目录


前言

并查集

一、并查集

并查集一共可以分为三步:
1.初始化
2.合并
3.查询

首先是初始化:

初始化是用一个数组来来记录自己(我们以谁是谁的先辈为例),初始化时,自己是自己的先辈。 初始化用如下代码表示:
 def init(length:int)->List[int]:
            return list(range(length))

用一个数组parent 来表示 parent[i] = j 表示 i的先辈是j。初始化是parent[i] = i,表示自己是自己的先辈。
接着是合并,例如3是4的先辈,2又是3的先辈。1又是2 的先辈 间接可以得出1又是4的先辈:如下图

合并就是根据需要合并的条件,将节点union起来。

最后是查询。其实查询与合并几乎是同时进行的,查询是寻找当前节点的先辈。如果新的节点连接起来,那么当前节点的的先辈,就要变换啦,变换为新的先辈。查询过程也是递归查询,代码如下:

 #find 找该节点的祖先
        def find(index:int)->int:
            if parent[index]!=index:
                parent[index] = find(parent[index])
            return parent[index]

二、LeetCode 例题

1.547.省份的数量

解题思路:
	#使用并查集的思想,将省份联通,因为联通的省份的先辈会变成别人。
	# 最后统计 有多少个 parent[i] = i 就可以啦

并查集解题都很有模板可循,代码如下:

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        """
        # 并查集
        """
        def init(length:int)->List[int]:
            return list(range(length))

        #find 找该节点的祖先
        def find(index:int)->int:
            if parent[index]!=index:
                parent[index] = find(parent[index])
            return parent[index]
        #合并
        def union(index1:int,index2:int):
            parent[find(index1)] = find(index2)
        
        length = len(isConnected)
        parent = init(length)

        for i in range(length):
            for j in range(i+1,length):
                if isConnected[i][j]==1:
                    union(i,j)
        
        ans = sum(parent[i]==i for i in range(length))
        print(parent) #这里可以输出看一下。
        return ans

2.684.冗余连接

代码如下(示例):
解题思路:
	#同样使用并查集,将边联通起来,在连接时,判断两个节点是否已经联通,
	#如果已经联通,则返回两个节点的值
	# 否则继续连接

也是套模板的样子,代码如下:

class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        def init(length:int)->List[int]:
            return list(range(length))

        #find 找该节点的祖先
        def find(index:int)->int:
            if parent[index]!=index:
                parent[index] = find(parent[index])
            return parent[index]
        #合并
        def union(index1:int,index2:int):
            parent[find(index1)] = find(index2)


        length = len(edges)

        parent = init(length+1)

        for i in range(length):
            if find(edges[i][0])!= find(edges[i][1]):
                union(edges[i][0],edges[i][1])
            else:
                return [edges[i][0],edges[i][1]]
        
        return []

总结

这是一个套模板的算法,大家理解就好。主要是注意查询和连接的条件啦~

举报

相关推荐

0 条评论