python 有效的字母异位词

本文介绍如何使用Python实现快速判断两个字符串s和t是否为字母异位词的方法,通过排序字符列表并比较是否相等。适合初学者理解字符串处理技巧。

| 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:

输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:

输入: s = “rat”, t = “car”
输出: false

提示:

1 <= s.length, t.length <= 5 * 104
s 和 t 仅包含小写字母

题解

class Solution:
    """
    通过给字符串排序解题
    """
    def isAnagram(self, s: str, t: str) -> bool:
        if len(s) != len(t):
            return False
        s_list = list(s)
        t_list = list(t)
        t_list.sort()
        s_list.sort()

        return ''.join(s_list) == ''.join(t_list) 
<think> 根据提供的引用内容,字母异位词分组问题可以通过多种方法解决。常见思路是:将每个单词通过某种规则转换为一个唯一的键(key),使得互为字母异位词的单词具有相同的键。然后利用哈希表(字典)将相同键的单词归为一组。 常用方法有: 1. 将单词按字母排序,排序后的字符串作为键(引用[5])。 2. 统计单词中每个字母出现的频次,用一个固定长度的数组(26维)表示,然后转换为元组作为键(引用[1])。 3. 使用计数器(Counter)统计字母频次,然后对频次字典的项排序后转为元组作为键(引用[3])。 下面分别展示这三种方法的代码实现: ### 方法1:字母排序法 互为字母异位词的单词排序后得到相同的字符串。 ```python from collections import defaultdict def groupAnagrams(strs): anagram_map = defaultdict(list) for word in strs: # 对单词的字符排序,并重新组合为字符串 sorted_word = ''.join(sorted(word)) anagram_map[sorted_word].append(word) return list(anagram_map.values()) ``` ### 方法2:计数数组法 使用长度为26的数组记录每个字母出现的次数,然后转换为元组作为键(因为元组是可哈希的)。 ```python from collections import defaultdict def groupAnagrams(strs): anagram_map = defaultdict(list) for word in strs: count = [0] * 26 # 26个字母的计数器 for char in word: # 计算字母在数组中的索引 index = ord(char) - ord('a') count[index] += 1 # 将计数数组转为元组作为键 key = tuple(count) anagram_map[key].append(word) return list(anagram_map.values()) ``` ### 方法3:使用Counter和排序的元组 使用`collections.Counter`统计字母频次,然后将频次字典的项排序后转为元组(因为字典不可哈希,而元组可以)。 ```python from collections import defaultdict, Counter def groupAnagrams(strs): anagram_map = defaultdict(list) for word in strs: # 使用Counter统计字母频次 counter = Counter(word) # 将字典的键值对按字母排序,然后转为元组 key = tuple(sorted(counter.items())) anagram_map[key].append(word) return list(anagram_map.values()) ``` ### 示例运行 对于输入`strs = ["eat", "tea", "tan", "ate", "nat", "bat"]`,以上三种方法都会输出类似的结果(分组顺序可能不同): ```python [ ["bat"], ["tan", "nat"], ["eat", "tea", "ate"] ] ``` 注意:实际输出中子列表的顺序可能不同,因为字典是无序的,但每个子列表内的单词都是互为字母异位词。 ### 性能比较 - 方法1:排序的时间复杂度为$O(k \log k)$(k为单词长度),整体时间复杂度为$O(n \times k \log k)$,其中n为单词个数。 - 方法2:计数数组的时间复杂度为$O(n \times k)$,因为每个单词遍历一次,每个字符操作是常数时间。 - 方法3:使用Counter统计频次的时间复杂度为$O(k)$,然后排序字典项的时间复杂度为$O(c \log c)$(c为不同字母个数,最多26),所以整体为$O(n \times (k + 26 \log 26))$,近似$O(n \times k)$。 如果单词长度较短,方法1可能更简洁;当单词较长时,方法2性能更优。 §§相关问题§§ 1. 字母异位词分组问题的时间复杂度如何分析? 2. 除了以上三种方法,还有哪些方法可以解决字母异位词分组问题? 3. 如何优化字母异位词分组算法以处理大量数据? </think> 以下是使用Python实现字母异位词分组的几种常用方法,基于您提供的引用内容: ### 方法1:使用排序后的字符串作为键(最常见方法) ```python from collections import defaultdict class Solution: def groupAnagrams(self, strs): anagram_map = defaultdict(list) # 创建默认字典 for word in strs: # 将单词按字母排序后作为键 sorted_word = ''.join(sorted(word)) anagram_map[sorted_word].append(word) # 添加到对应分组 return list(anagram_map.values()) # 返回分组结果 ``` **示例使用**: ```python strs = ["eat", "tea", "tan", "ate", "nat", "bat"] print(Solution().groupAnagrams(strs)) # 输出: [['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']] ``` ### 方法2:使用字符计数元组作为键(优化性能) ```python from collections import defaultdict class Solution: def groupAnagrams(self, strs): anagram_map = defaultdict(list) for word in strs: count = [0] * 26 # 26个字母的计数器 for char in word: # 计算字符在字母表中的位置 idx = ord(char) - ord('a') count[idx] += 1 # 将计数数组转为元组作为键 key = tuple(count) anagram_map[key].append(word) return list(anagram_map.values()) ``` ### 方法3:使用Counter统计字符频率(灵活但稍慢) ```python from collections import defaultdict, Counter class Solution: def groupAnagrams(self, strs): anagram_map = defaultdict(list) for word in strs: # 统计字符频率并排序键值对 counter = Counter(word) key = tuple(sorted(counter.items())) # 排序后转为元组 anagram_map[key].append(word) return list(anagram_map.values()) ``` ### 代码说明: 1. **核心思路**:互为字母异位词的单词具有相同的"特征",通过提取特征作为哈希表的键 2. **时间复杂度**: - 方法1:$O(n \times k \log k)$(n为单词数,k为单词长度) - 方法2:$O(n \times k)$(性能最优) - 方法3:$O(n \times (k + c \log c))$(c为不同字符数) 3. **空间复杂度**:$O(n \times k)$(存储所有单词) 对于大多数应用场景,**方法1**(排序法)最为简洁实用;当处理大量长单词时,**方法2**(计数法)性能更优[^1][^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶知秋的BLOG

创作不易 请多多关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值