并查集解题

在刷题过程中遇到并查集方法,在此记录:
对并查集思路尝试解释:
1.创建parent表,初始值为表中parent[x]=x,即默认初始时所有子块分别为单独子块,cnt记录连通子块个数(初始为len)
2.find函数:查找根节点,不断向上追溯
3.connected函数:使用find判断当前两位置的根节点位置是否相同,如果相同,在union中返回空值跳过后续
4.union函数:将根节点不同的子块连通(通过将根节点1在parent中的位置数值由1改为2)连通一次子块个数cnt-1.
力扣947:
并查集解题_第1张图片

在这里插入class UF:
    def __init__(self, M):
        self.parent = {}
        self.cnt = 0
        # 初始化 parent,size 和 cnt
        for i in range(M):#self.parent记录位置信息(第i个初始值即为i)
            self.parent[i] = i
            self.cnt += 1#连通子块数初始为长度,每个值视为一个连通子块

    def find(self, x):#希望通过x位置得到根节点的位置信息
        if x != self.parent[x]:#如果x位置信息不等于self.parent中对应信息,
            self.parent[x] = self.find(self.parent[x])#找到上一节点,依次上找
            return self.parent[x]#返回根节点
        return x#不存在连通信息,返回本身
    def union(self, p, q):
        if self.connected(p, q): return#如果连通,则不连接
        leader_p = self.find(p)#p的根节点
        leader_q = self.find(q)#q的根节点
        self.parent[leader_p] = leader_q#将子块连通
        self.cnt -= 1#连通子块数-1
    def connected(self, p, q):#如果存在相同根节点,则返回(true),不进行连接操作
        return self.find(p) == self.find(q)

class Solution:
    def removeStones(self, stones: List[List[int]]) -> int:
        #创造表放入值,值已存在则删除
        #出现问题:难以保证此时为删除的最大数量
        #重新解题:逆推,当该点存在同一边点,剔除该点,循环直到只有一个点,因此一个连通块只剩一个点
        #使用并查集可以很好地解决该问题
        #即总长减去连通块个数,即为最大数
        #即问题转化为如何求最大连通子块数量
        pa=UF(len(stones))
        #开始对子块连通,判断条件为行列是否相等,每一个子块与其他子块比较
        for i in range(len(stones)):
            for j in range(i+1,len(stones)):
                if stones[i][0]==stones[j][0] or stones[i][1]==stones[j][1]:
                    pa.union(i,j)
        return len(stones)-pa.cnt代码片

你可能感兴趣的:(算法,python)