字母异位词分组
1.思路
这题耗费了很多时间,一开始想的是从头开始遍历列表中的每个字符串,然后创建一个列表str_each_list来记录每一个字符串的字母,接着第二遍遍历列表,判断后续字符串的长度是否等于str_each_list的长度且str_each_list是否in后续字符串,如果是,则表明是字母异位词。但是调试了一下,发现结果并不对,是因为仅仅判断str_each_list是否in后续字符串是远远不够的。
然后我又想到用集合的issubset方法来判断,但集合中不能有重复元素,如果我遍历的字符串中有重复的字母该怎么办呢?所以这种方法也被pass掉。接着我就想到用字典来存储每一个字符串的特征,key为字符串中出现的字母,value对应为该字母出现的次数。我又引入了Counter方法,这样在后面判断条件只需要判断Counter(遍历到的字符串)==my_dict即可,就在我信心满满地改完提交后,一个99KB的测试用例又把我拒之门外……
from collections import Counter
class Solution:
def groupAnagrams(self, strs: list[str]) -> list[list[str]]:
"""
对于strs中的每一个str,创建一个字典以记录str中的每一位出现的次数,
遍历后续str,如果Counter(str)与字典中的值相等,说明他们是字母异位词,
则将str加入到对应的字母异位词列表中。
"""
strs_len=len(strs)
result=[]
for index in range(strs_len):
if any(strs[index] in group for group in result):
continue
else:
anagram_group=[]
anagram_group.append(strs[index])
str_each_dict=dict()
for each in strs[index]:
str_each_dict[each]=strs[index].count(each)
for index_1 in range(index+1,strs_len):
if Counter(strs[index_1])==str_each_dict:
anagram_group.append(strs[index_1])
result.append(anagram_group)
return result
我在上面的代码的基础上又进行了一些优化,比如放弃用any来判断后序遍历到的字符串是否出现在result中,转而用一个集合used来存储每一次加入到字母异位词的列表元素,但结果还是无济于事,依然超出时间限制。
2.解题方法
最终我还是选择了官方解法,官方解法的思路是先创建一个value为字典的列表,然后将每个乱序后的字符串作为key,再把字符串加入到列表里,可以这么做的原因是因为字母异位词经过sorted后是一样的。
3.Code
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
my_dict=collections.defaultdict(list)
for st in strs:
key=''.join(sorted(st))
my_dict[key].append(st)
return list(my_dict.values())