49. 字母异位词分组

暴力 hash

没有给输入样例长度
对list里面的每个单词统计里面的字母和词频,得到由这些字母组成的字典

如果两个字母对应的字典是相同的,那么它们就是字母异位词

现在的问题就是找到字典下对应的所有字母异位词即可,直接构造不可取,一共有n!种组合,还要比较,直接遍历原来的list即可

但是字典不能在python中hash,我们转换成用下标来hash,用que来存放队列,添加时用in来判断字典是否在里面

虽然这个字母都是小写字母,但是根据我的经验判断,使用库dict比自己手写开数组效率要高

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        que = []
        sm = dict()
        for i in strs:
            t = Counter(i)
            sm[i] = t
            # 比较n次
            if t not in que:
                que.append(t)

        mp = defaultdict(list)

        for i in strs:
            t = sm[i]
            mp[que.index(t)].append(i)

        ans = list(mp.values())

        return ans

在这里插入图片描述

时间复杂度 O ( N 2 ) O(N^2) O(N2),在第一个for中判断是否存在队列也是O(N)级别的开销,第二个for里面,que.index()也是O(N)级别的算法

sort

开始有想过sort,但是被nlogn的时间复杂度劝退了
不过写了一下,发现效率变高了

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        mp = defaultdict(list) 

        for i in strs:
            mp["".join(sorted(i))].append(i)

        return list(mp.values())

用sorted过后的字符串作为key,很容易就能得到答案

时间复杂度这里是 O ( n k l o g k ) O(nklogk) O(nklogk),k是字符串的长度,n是字符串的个数

在这里插入图片描述

计数

和暴力一样的思路,不过这里是手动开数组,然后转换成tuple作为key存放到tuple里面,确实简洁了很多

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        mp = defaultdict(list) 

        for s in strs:
            bucket = [0] * 26
            for ch in s:
                bucket[ord(ch) - ord('a')] += 1
            mp[tuple(bucket)].append(s)

        return list(mp.values())

在这里插入图片描述
在这里插入图片描述

现在回过头来看第一次写的暴力,写得太混乱了,转了两次map,只需要一个map就行

prime hash

使用hash的原理来解题,由于字母的范围是小写字母,将它们唯一映射到质数上,然后对于每个字符串,计算它们的乘积,只有异构字符串的乘积会是一样

primes = {'a': 2, 
                  'b': 3, 
                  'c': 5, 
                  'd': 7, 
                  'e': 11, 
                  'f': 13,
                  'g': 17,
                  'h': 19,
                  'i': 23,
                  'j': 29,
                  'k': 31,
                  'l': 37,
                  'm': 41,
                  'n': 43,
                  'o': 47,
                  'p': 53,
                  'q': 59,
                  'r': 61,
                  's': 67, 
                  't': 71,
                  'u': 73,
                  'v': 79,
                  'w': 83,
                  'x': 89,
                  'y': 97,
                  'z': 101
                 }
        
        
        subLists = {}
        
        for string in strs:
            product = 1
            
            for character in string:
                product = primes[character] * product
            
            if product in subLists.keys():
                listA = subLists[product]
                listA.append(string)
                subLists[product] = listA
            else:
                subLists[product] = [string]
                
        listToReturn = []
        
        for value in subLists.keys():
            listToReturn.append(subLists[value])
            
        return listToReturn

ref: https://leetcode.com/problems/group-anagrams/solution/

改动了一下,几乎是最快的解法

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        primes = {'a': 2, 
                  'b': 3, 
                  'c': 5, 
                  'd': 7, 
                  'e': 11, 
                  'f': 13,
                  'g': 17,
                  'h': 19,
                  'i': 23,
                  'j': 29,
                  'k': 31,
                  'l': 37,
                  'm': 41,
                  'n': 43,
                  'o': 47,
                  'p': 53,
                  'q': 59,
                  'r': 61,
                  's': 67, 
                  't': 71,
                  'u': 73,
                  'v': 79,
                  'w': 83,
                  'x': 89,
                  'y': 97,
                  'z': 101
                 }
        
        
        subLists = {}
        
        for string in strs:
            product = 1
            
            for character in string:
                product = primes[character] * product
            
            if product in subLists.keys():
                subLists[product].append(string)
            else:
                subLists[product] = [string]
                
            
        return list(subLists.values())

python里面不用担心溢出的问题

总结

早上思路有些混乱,写出来的暴力很难看
其实思路是想到了,就是统计字典,然后反过来映射这个字典构造出来的字符串,但是实现的方法不是很好,导致效率很低

计数和sort方法都是构造出key,然后存放进dict里面,然后直接取value就行
我的暴力先是统计每个str的dict存放到que队列里面,que中每个dict唯一,然后再重新遍历str,按照key:que中的下标,value:str的格式存放到最终的dict里面

最后一个用质数乘积来作为key的思想很巧妙

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值