LeetCode 49. Group Anagrams (Python)

本文介绍了一种有效的算法来解决将字符串列表中的同字母异序词分组的问题。通过将每个字符串排序并以此作为键值存储在字典中,可以快速找到所有由相同字母组成的字符串。该算法简洁高效,易于理解和实现。

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

题目描述:
Given an array of strings, group anagrams together.

For example, given: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Return:

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

Note: All inputs will be in lower-case.

思路:
首先对所给的字符串列表(数组)进行排序,即对其中的每一个字符串都进行排序,这样就可以得到哪些字符串是归位一组的。
接着将字符串列表转换为一个字典,并遍历key值得到最终的列表返回。

AC代码:

class Solution(object):
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        ans, res, ret = [], {}, []
        for s in strs:
            temp = list(s)
            temp.sort()
            ans.append("".join(temp))
        for i in range(len(ans)):
            if ans[i] not in res:
                res[ans[i]] = []
            res[ans[i]].append(strs[i])
        for key in res:
            ret.append(res[key])
        return ret
### 问题解析 LeetCode49题 **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 ``` --- ### 总结 上述几种方法均能正确解决 LeetCode49题,差异主要体现在数据结构的使用、代码风格以及性能优化上。推荐优先使用第一种或第二种方法,因其简洁高效,适合大多数实际场景。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值