检查两个字符串是不是是字谜的运行时间应该是多少

Posted

技术标签:

【中文标题】检查两个字符串是不是是字谜的运行时间应该是多少【英文标题】:What should be the runtime of checking if two strings are anagrams检查两个字符串是否是字谜的运行时间应该是多少 【发布时间】:2017-02-10 04:58:36 【问题描述】:

我写了这个函数,我认为运行时间是 O(nlogN),但我不确定。另外,是否有更清洁的方式来编写这个(java)?我觉得一个更有经验的程序员可以用更少的代码行来做到这一点。

public static boolean anagramCheck(String strA, String strB)
  if(strA.length() != strB.length())
  return false;


char arrA[] = strA.toCharArray();
char arrB[] = strB.toCharArray();

Arrays.sort(arrA);
Arrays.sort(arrB);

int j = 0;
for(char s : arrA)
    if(s != arrB[j])
        return false;
    
     j++;
  
    return true;

【问题讨论】:

O(n) - 使用哈希表计算频率并与第二个比较。 @AlexeiLevenkov,这几乎不是 O(n)。您冒着在哈希表中发生冲突的风险。如果有,它们会降低性能。 【参考方案1】:

排序相对昂贵 - O(n log n) - 如果可能,一般应避免。

您可以通过对每个字符串进行一次传递来收集字符频率,将时间复杂度降低到 O(n),然后可以使用 Map#equals 进行比较。

这可以只用一行来完成:

return strA.chars().boxed().collect(Collectors.groupingBy(i -> i, Collectors.counting()))
  .equals(strB.chars().boxed().collect(Collectors.groupingBy(i -> i, Collectors.counting())));

Try it online.


怀疑此代码实际上具有 O(n) 时间复杂度的人可以看到 live timing test 显示每个字母的恒定时间 - 即 O(n)(其中 n 是字母中的单词长度)。

【讨论】:

无法编译。纠正了这个错误,我相信我对 Alexei Levenkov 的评论在这里也是有效的:使用地图几乎不是 O(n)。 @ole 感谢您指出编译问题。它需要.boxed()(在 iPhone 上翻阅代码的危险之一 - 现已修复并添加了实时演示链接)。是的,这是 O(n),因为 HashMap 上的所有操作都是 O(1)。比较小于 O(n)(由于重复),因此不考虑在内。 我仍然对 O(n) 声明感到好奇。 HashMap 仅当“散列函数将元素正确分散在桶中”时才保证恒定时间操作。这可能(或可能不)适用于一般字符,但谁知道字谜候选中的字符呢? @Ole String#chars()IntStream 的形式返回字符,它(在装箱到Integer 之后)有自己的哈希码,所以不会有哈希冲突,HashMap 的内部哈希算法将使用这些 int 哈希码可以将字符均匀地分布在桶中。 可能。我不相信。【参考方案2】:

算法的时间复杂度为 O(nlogn)。

【讨论】:

以上是关于检查两个字符串是不是是字谜的运行时间应该是多少的主要内容,如果未能解决你的问题,请参考以下文章

为了检查两个字符串是不是是字谜, hashfunction() 的逻辑应该是啥?

Python - 比较 2 个单词并检查它们是不是是字谜

使用 C++ 检查两个字符串是不是是字谜

如何检查两个字符串是不是是字谜?

使用基本Java检查两个字符串是不是是彼此的字谜[重复]

检查需要删除多少个字符才能在 Python 中生成字谜