zoukankan      html  css  js  c++  java
  • leetcode 839 Similar String Groups

    题目#

    Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it equals Y.

    We are given a list A of strings. Every string in A is an anagram of every other string in A. How many groups are there?

    anagram 这个词的意思被忽略导致我误理解了题意

    Intuition#

    我们可以在 Ow 的时间内分辨 两个words 是否相似

    一种思想是纯使用暴力算法 : n2W 的时间内判断两个单词是否详细

    另一种想法是 枚举一个单词的所有相似紧邻 一个单词之多有 C2w 个紧邻

    W2 的时间用来枚举所有的可能相似单词 W 时间
    这样我们可以使用 ONW3 的时间 列出所有的单词相邻
    py2 版本

    class DSU(object,N):
        def __init__(self):
            self.par=range(N)
        def find(self,x):
            if(self.par[x]!=x):
                self.par[x]= self.find(par[x])
                return self.par[x]
        def union(self,x,y):
            if(x!=y):
                self.par[self.find(x)]=self.find(y)
    class Solution(object):
        def numSimilarGroups(self,A):
            N,w=len(A),len(A[0])   # 分别是词的个数和 词的长度
            def similar(W1,W2):
                diff=0
                for x,y in itertools.izip(W1,W2):
                    if x!=y:
                        diff=dfif+1
                return diff <=2
            
            dsu=DSU(N)
    
            if(N<W*W): //如果整个词列表较短, 遍历整个词列表进行计算会更快
                for (i1,word1),(i2,word2) in itertools.combinations(enumerate(A),2):#高效的枚举操作 ,也是py支持的非常有用的操作
                    if similar(word1,word2):
                        dsu.union(i1,i2)  #使用编号作为合并的索引
            else:
                buckets=collections.defaultdict(set) # values 是set 且具有默认值的字典
                for i,word in enumerate(A):
                    L=list(word) # string 调换中间某几个字符顺序的最佳操作
                    for j0,j1 in itertools.combinations(xrange(N),2):   组合操作的最佳方式 使用itertools 
                        L[j0], L[j1] = L[j1], L[j0]
                        buckets["".join(L)].add(i)
                        L[j0], L[j1] = L[j1], L[j0]
                for i1, word in enumerate(A):
                    for i2 in buckets[word]:
                        dsu.union(i1, i2)                                             
                 return sum([for dsu.par[x]==x for x in range(N)]) #并查集变通块数量的查询简易方法
    

    以上的代码虽然正确,但是复杂度高 ,不能通过(py3 的方式重写之后 不能通过py3 的测试)
    下面是 加速版本

    class Solution:
        def numSimilarGroups(self, A):
            SA = set(A)  # to delete duplicate items
            A = list(SA) # make it indexable
            L = len(A)
            base = [i for i in range(L)]
            
            def find(x):
                if base[x] != x:
                    base[x] = find(base[x])
                return base[x]
            
            def union(x, y):
                base[find(x)] = find(y)
                
            def check(x, y):
                return sum(a!=b for a, b in zip(A[x], A[y])) == 2
            
            if L < len(A[0])**2:  # deal with long word with few items
                for i1, i2 in itertools.combinations(range(L), 2):
                    if check(i1, i2):
                        union(i1, i2)
            else: # deal with short word with lots of items
                buckets = collections.defaultdict(set)
                for i, word in enumerate(A):
                    for i1, i2 in itertools.combinations(range(len(word)), 2):
                        if word[i1] != word[i2]:  # filter, otherwise it will exceed memory limit
                            wl = list(word)
                            wl[i1], wl[i2] = wl[i2], wl[i1]
                            key = "".join(wl)
                            if key in SA:
                                buckets[key].add(i)
    
                for i, word in enumerate(A):
                    for j in buckets[word]:
                        union(i, j)
                        
            return sum(base[x] == x for x in range(L))
    

    可以看到 这里将dsu 单独拿出来使用,
    然后在枚举 一个单词的所有邻居的时候 也进行了优化 就是如果这个单词的两个位置不一样 我们才认为是一个合法的邻居。

  • 相关阅读:
    洛谷P2522 [HAOI2011]Problem b(莫比乌斯反演)
    洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)
    Informatica PowerCenter 常用转换组件一览表
    Informatica_(3)组件
    Informatica_(2)第一个例子
    Informatica_(1)安装
    InformaticaPowerCenter调用存储过程
    Informatica 9.5.1 安装配置
    Linux字符集的查看及修改
    Redis-3.2.9集群配置(redis cluster)
  • 原文地址:https://www.cnblogs.com/sfzyk/p/9250477.html
Copyright © 2011-2022 走看看