Leetcode 839 相似字符串组


from typing import List

'''
并查集求连通分量个数
'''

class MergeSet:
    def __init__(self):
        self.m = {}
        self.__root_cnt = 0

    def getRoot(self, node):
        root = node
        buf = []
        while self.m[root] != root:
            buf.append(root)
            root = self.m[root]
        for node in buf:
            self.m[node] = root

        return root


    def merge(self, a, b):
        for node in [a, b]:
            if node not in self.m:
                self.m[node] = node
                self.__root_cnt += 1

        root1 = self.getRoot(a)
        root2 = self.getRoot(b)
        if root1 != root2:
            self.m[root1] = root2
            self.__root_cnt -= 1

    def isInSameSet(self, a, b):
        for node in [a, b]:
            if node not in self.m:
                return False

        return self.getRoot(a) == self.getRoot(b)

    def getRootNum(self):
        return self.__root_cnt

    def getClusters(self):
        rec = {}
        for node in self.m:
            root = self.getRoot(node)
            if root not in rec:
                rec[root] = []
            rec[root].append(node)
        return [nodes for nodes in rec.values()]


class Solution:
    def numSimilarGroups(self, A: List[str]) -> int:

        def check(str1, str2):
            if str1 == str2:
                return True

            cnt = 0
            for i in range(len(str1)):
                if str1[i] != str2[i]:
                    cnt += 1
                    if cnt >= 3:
                        return False
            return cnt == 2

        N, M  = len(A), len(A[0])

        if N <= M:
            merge_set = MergeSet()
            for i in range(len(A)):
                merge_set.merge(i, i)

            for i in range(len(A)):
                for j in range(i+1, len(A)):
                    str1, str2 = A[i], A[j]

                    if (not merge_set.isInSameSet(i, j)) and check(str1, str2):
                        merge_set.merge(i, j)
            return merge_set.getRootNum()

        else:
            merge_set = MergeSet()
            for word in A:
                merge_set.merge(word, word)


            all_words = set(A)
            for word in A:
                for i in range(len(word)):
                    for j in range(i+1, len(word)):
                        new_word = word[:i] + word[j] + word[i+1:j] + word[i] + word[j+1:]
                        if new_word in all_words:
                            merge_set.merge(word, new_word)
            return merge_set.getRootNum()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值