839. Similar String Groups

解法

中心思想是用并查集,关键点是联系的输入
两种方法:

  1. 枚举list里两两字符串之间的相系,适合词少的时候
  2. 遍历每个字符,枚举它可能到达的字符,适合词多的时候
    假设字符串s可以到达t,注意这里是存的是t到s的边,因为set[i]要存i字符串可以到达的在list里的字符串的集合

点:

  1. 词稀疏和稠密适合不同的算法
  2. 注意最后统计的时候同一个s不要统计2次

标准答案里并查集用的是数组下标,我用的是字符串hash,反正也过了,懒得改了

class Solution(object):
    def numSimilarGroups(self, A):
        """
        :type A: List[str]
        :rtype: int
        """
        import itertools
        f = {}
        n = len(A)
        if n==0:
            return 0
        w = len(A[0])

        def is_similar(a,b):
            l = len(a)
            rest = 2
            for i in xrange(l):
                if a[i]!=b[i]:
                    rest -= 1
                    if rest<0:
                        return False
            return rest>=0

        def find(x):
            if x not in f:
                f[x]=x
                return x
            r = x
            while f[r]!=r:
                r = f[r]
            while x!=r:
                tmp = f[x]
                f[x] = r
                x = tmp
            return r

        def join(x,y):
            f[find(y)]=find(x)

        if n<w*w:
            for i in xrange(n-1):
                for j in xrange(i,n):
                    if is_similar(A[i],A[j]):
                        join(A[i],A[j])
        else:
            from collections import defaultdict
            edges = defaultdict(set)
            for string in A:
                L = list(string)
                for j1,j2 in itertools.combinations(xrange(w), 2):
                    L[j1], L[j2] = L[j2], L[j1]
                    edges["".join(L)].add(string)
                    L[j1], L[j2] = L[j2], L[j1]
            for string in A:
                for word in edges[string]:
                    join(string, word)
        return len(filter(lambda x:x not in f or f[x]==x, set(A)))

猜你喜欢

转载自blog.csdn.net/lemonmillie/article/details/84945126