【发布时间】:2011-05-09 06:59:40
【问题描述】:
在 Skiena 的“算法设计手册”一书中,计算集合的 众数(最常见元素),据说有一个 Ω(n log n) 下限(这让我很困惑),而且(我猜对了)没有更快的最坏情况算法来计算模式。我只是对 Ω(n log n) 的下限感到困惑。
查看本书页面Google Books
但在某些情况下,这肯定可以在线性时间内计算(最佳情况),例如通过如下 Java 代码(在字符串中查找最常见的字符),“技巧”是使用哈希表计算出现次数。这似乎很明显。
那么,我对这个问题的理解缺少什么?
编辑:(谜团已解决)正如 StriplingWarrior 指出的那样,如果仅使用比较,即不使用内存索引,则下限成立,另请参阅:http://en.wikipedia.org/wiki/Element_distinctness_problem
// Linear time
char computeMode(String input) {
// initialize currentMode to first char
char[] chars = input.toCharArray();
char currentMode = chars[0];
int currentModeCount = 0;
HashMap<Character, Integer> counts = new HashMap<Character, Integer>();
for(char character : chars) {
int count = putget(counts, character); // occurences so far
// test whether character should be the new currentMode
if(count > currentModeCount) {
currentMode = character;
currentModeCount = count; // also save the count
}
}
return currentMode;
}
// Constant time
int putget(HashMap<Character, Integer> map, char character) {
if(!map.containsKey(character)) {
// if character not seen before, initialize to zero
map.put(character, 0);
}
// increment
int newValue = map.get(character) + 1;
map.put(character, newValue);
return newValue;
}
【问题讨论】:
-
勘误表中似乎没有提及:cs.sunysb.edu/~skiena/algorist/book/errata
-
无法读取页面。一些古怪的信息,显然是丹麦语。
-
把 google.dk 改成 google.com,就可以了。
-
修复了指向 google.com 的链接 :)
-
别管哈希图,它们会因为可疑的复杂性声明而分散注意力。考虑在仅由“0”和“1”组成的序列中找到最频繁元素的问题。 显然这是线性时间,只需计算事物(同样您可以按线性时间对它们进行排序,最简单的桶排序情况)。正如 StriplingWarrior 所说,具有此界限的是问题的比较版本,就像 comparison 排序具有 Big_Omega(n log n) 下限一样。大概当本书更早地定义其术语时,它以某种方式限制了讨论。