LeetCode--Group Anagrams(Python)

本文介绍了一种使用哈希表快速实现字符串分组的算法。通过排序字符串并利用字典存储,可以高效地将包含相同字符的字符串进行分组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给定一个数组,如["eat", "tea", "tan", "ate", "nat", "bat"],将其按照包含字符分组,分组结果如

[
  ["ate", "eat","tea"],
  ["nat","tan"],
  ["bat"]
]

解题思路:

考虑使用哈希表,加快速度。先将所有的字符串各自排序,将排序后的字符串逐一放到dict里,若dict中已存在该字符串,则跳过,否则将该字符串放入dict,且count+1,用count来记录当前字符串为第几组。

经过上述步骤,当前dict中存储的是排序后的字符串及各自对应的组号。再将原字符串根据排序后在字典中的value,依次加入到对应序号的输出列表即可。

代码(python):

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        strs_c = copy.deepcopy(strs)
        dict_s = {}
        count = 0
        
        for i in range(len(strs_c)):
            temp = list(strs_c[i])
            temp.sort()
            strs_c[i] = ''.join(temp)
        
        for i in range(len(strs_c)):
            if strs_c[i] not in dict_s:
                dict_s[strs_c[i]]=count
                count=count+1
        
        output = [ [ ] for i in range(count) ]
        
        for i in range(len(strs)):
            output[dict_s[strs_c[i]]].append(strs[i])
           
        return output

### 问题解析 LeetCode 第49题 **Group Anagrams** 要求将字符串数组中的字母异位词(即由相同字符以不同顺序组成的字符串)归为一组。例如,输入 `["eat", "tea", "tan", "ate", "nat", "bat"]`,输出应为: ```python [ ["eat", "tea", "ate"], ["tan", "nat"], ["bat"] ] ``` 解决该问题的核心思路是找到一个统一的“特征”来标识每个异位词组。通常有两种方法实现这一点。 --- ### 方法一:排序作为键值 对于每个字符串,将其字符排序后得到的字符串可以作为字典的键。所有互为异位词的字符串在排序后会生成相同的键[^1]。 #### Python 实现 ```python from typing import List class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: counts = dict() for s in strs: key = ''.join(sorted(s)) if key in counts: counts[key].append(s) else: counts[key] = [s] return list(counts.values()) ``` - 时间复杂度:O(n * k log k),其中 n 是字符串数量,k 是单个字符串的平均长度。 - 空间复杂度:O(n * k) --- ### 方法二:字符计数作为键值 另一种方式是以字符频率元组作为字典的键。例如,字符串 `"aab"` 的频率元组是 `(2, 1, 0, ..., 0)`,表示每个字母出现的次数。由于列表不能作为字典的键,因此使用元组形式存储[^2]。 #### Python 实现 ```python from collections import defaultdict from typing import List class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: dic = defaultdict(list) for w in strs: count = [0] * 26 for c in w: count[ord(c) - ord('a')] += 1 dic[tuple(count)].append(w) return list(dic.values()) ``` - 时间复杂度:O(n * k),其中 k 是字符串长度。 - 空间复杂度:O(n * k) --- ### 方法三:逐行分析与手动构建结果 以下代码通过显式构建字典和结果列表完成分类。其逻辑清晰,适合初学者理解流程[^3]。 ```python from typing import List class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: res = [] mdict = {} for word in strs: sorted_word = ''.join(sorted(word)) if sorted_word in mdict: mdict[sorted_word].append(word) else: mdict[sorted_word] = [word] for value in mdict.values(): res.append(value) return res ``` --- ### 方法四:使用索引映射 该方法先建立排序后的字符串到原始索引之间的映射,然后根据映射关系组织最终结果[^4]。 ```python from typing import List class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: dict1 = {} for i, s in enumerate(strs): key = ''.join(sorted(s)) if key not in dict1: dict1[key] = [i] else: dict1[key].append(i) res = [] for indices in dict1.values(): group = [strs[i] for i in indices] res.append(group) return res ``` --- ### 方法五:异常处理机制实现 此解法尝试通过异常捕获机制动态更新结果数组,适用于不希望预先初始化字典的情况[^5]。 ```python from typing import List class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: result = [] sMap = {} index = 0 flag = 0 for originS in strs: s = list(originS) s.sort() key = ''.join(s) try: sLocate = sMap[key] flag = 1 except KeyError: sMap[key] = index index += 1 tempList = [originS] result.append(tempList) flag = 0 if flag == 1: result[sLocate].append(originS) return result ``` --- ### 总结 上述几种方法均能正确解决 LeetCode 第49题,差异主要体现在数据结构的使用、代码风格以及性能优化上。推荐优先使用第一种或第二种方法,因其简洁高效,适合大多数实际场景。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值