我在一次采访中收到了这个问题,并编码出了一个解决方案,但它并不是最优的.

给出一系列的单词,如:

军队,拉米,cat ,吃,茶……

How can you store these words to support the following query:
Given a word return list of anagrams present in the stream

实施方法:

public void storeWords(String[] words);
public String[] getAnagrams(String word);

例如:

  • getAnagrams("army")会返回["army", "ramy"]
  • getAnagrams("tac")会返回["cat"]

我需要它有O(1)的时间复杂度来查找getAnagram(),这意味着StoreWords()需要以一种不需要循环查找的方式来存储字形.目前,我的解决方案的运行时间为O(N)次,因为我使用的是循环.我不确定如何着手优化这一点.我在想也许可以使用Trie,但我不知道如何使用它来给我一个O(1)解

我的解决方案是:

  1. 创建一个Anagram_map,该映射接受其Unicode数字的key:sum和,以及具有该Unicode和的单词列表
    • ex.类别将是关键字:顺序(C)+顺序(A)+顺序(T)和值:[类别]
  2. GetAnagram将从传入的单词的Unicode数字总和中获取可能的字谜列表.然后,我有一个isAnagram的帮助器函数,它判断单词是否是给定单词的变形词
  3. IsAnagram有一个 map ,可以统计字形和单词的字数.如果 map 中的所有内容的计数都为0,则它是字谜
  4. 将其追加到我们返回的列表中

我的代码如下:

from collections import defaultdict
class Anagram:
    def __init__(self):
        self.anagram_map = defaultdict(list)
    
    def storeWords(self, words):
        for word in words:
            unicode_sum = 0

            for c in word:
                unicode_sum += ord(c)

            self.anagram_map[unicode_sum].append(word)

    def getAnagrams(self, word):
        unicode_sum = 0
        res = []
        
        for c in word:
            unicode_sum += ord(c)
            
        anagrams = self.anagram_map[unicode_sum]
        
        for anagram in anagrams:
            if self.isAnagram(anagram.word):
                res.append(anagram)
        
        return res
    
    def isAnagram(self, anagram, word):
        count_map = {}
        
        for c in anagram:
            if c in count_map:
                count_map[c] += 1
            else:
                count_map[c] = 1
        
        for w in word:
            if w in count_map:
                count_map[w] -= 1
            else:
                return False
        
        for count in count_map.values():
            if count != 0:
                return False
        
        return True

anagram = Anagram()

stream = ['army', 'ramy', 'cat', 'eat','tea']

anagram.storeWords(stream)

print(anagram.getAnagrams('army'))

print(anagram.getAnagrams('tac'))

有人知道我怎样才能优化这一点吗?

推荐答案

要检测字谜,使用ascii值来计算散列并不是获得唯一散列的有效方法,并且需要单独处理冲突.例如,以下2个字符串将具有相同的ASCII总和:

abd -> 295
bcb -> 295

相反,您可以对字符串中的字符进行排序,并将此排序状态用作字典键,并存储具有相同排序状态的所有单词,因为所有字谜在排序时都将具有相同的状态.

abc, cab, bca, acb --> abc(sorted state)

这样,对于大多数测试用例,您可以在平均O(1)时间内获得给定单词的所有字形.

Snippet:

class Anagram:
    def __init__(self):
        self.anagram_map = dict()
    
    def storeWords(self, words):
        for word in words:
            sortW = ''.join(sorted(word))
            self.anagram_map[sortW] = self.anagram_map.get(sortW, [])
            self.anagram_map[sortW].append(word)

    def getAnagrams(self, word):
       return self.anagram_map.get(''.join(sorted(word)), [])

Live Demo

Python相关问答推荐

在for循环中保存和删除收件箱

使用pandas MultiIndex进行不连续 Select

Pandas使用过滤器映射多列

pandas DataFrame中类型转换混乱

Python主进程和分支进程如何共享gc信息?

模型序列化器中未调用现场验证器

三个给定的坐标可以是矩形的点吗

Deliveryter Notebook -无法在for循环中更新matplotlib情节(保留之前的情节),也无法使用动画子功能对情节进行动画

ModuleNotFound错误:没有名为Crypto Windows 11、Python 3.11.6的模块

如何将双框框列中的成对变成两个新列

在Pandas DataFrame操作中用链接替换'方法的更有效方法

scikit-learn导入无法导入名称METRIC_MAPPING64'

C#使用程序从Python中执行Exec文件

如何在WSL2中更新Python到最新版本(3.12.2)?

连接一个rabrame和另一个1d rabrame不是问题,但当使用[...]'运算符会产生不同的结果

如何更新pandas DataFrame上列标题的de值?

我的字符串搜索算法的平均时间复杂度和最坏时间复杂度是多少?

Python全局变量递归得到不同的结果

如何使用两个关键函数来排序一个多索引框架?

手动设置seborn/matplotlib散点图连续变量图例中显示的值