【问题标题】:Find frequent occuring letter in log(n) time?在 log(n) 时间内查找频繁出现的字母?
【发布时间】:2015-06-07 16:48:03
【问题描述】:

如果给定一个字符串,例如 "aaabbccc",你将如何输出 'a',因为它与 'c' 一样频繁出现,但首先出现。

我使用了 O(n) 时间,但我不知道你将如何使用 log(n) 时间来做到这一点,无论是在 java 还是 c++ 中。

编辑: 这是一道面试题。

#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::cin;
using std::endl;

char findFreqChar(string str) {
    int count;
    int maxOccur = 0;
    char maxChar;
    for (char i = 'A'; i < 'z'; i++) {
        count = 0;

        for (int j = 0; j < str.length(); j++) {
            if (i == str[j])
                count++;
        }
        if (count > maxOccur) {
            maxOccur = count;
            maxChar = i;
        }
    }
    return maxChar;
}
int main() {
    std::cout << "Enter String: ";
    std::string str;
    std::getline(std::cin, str);
    cout << findFreqChar(str);
    cin.get();
}

【问题讨论】:

  • 拆分它?并继续拆分?
  • 这个问题更适合cs.stackexchange.com
  • 我很确定面试问题不是这样制定的。

标签: java c++ string letter


【解决方案1】:

如果您需要在 O(log(n)) 时间内完成此操作,那么这表明您需要开发某种类型的分治算法。我假设(基于你给我们的例子),一个字母的所有出现都是连续的。因此,我们可以做到以下几点:

1) 将数组一分为二,递归调用算法。子算法必须返回 4 个值: - 数组中出现频率最高的值及其频率 - 以最右边字符结尾的连续字符数 - 以最左边字符结尾的连续字符数

因此,当针对“aabbbbcc”调用时,递归调用将返回: (b, 4, 2, 2)

2) 合并两个子数组并返回(现在更大的数组)的结果。首先,我们需要计算组合数组中出现频率最高的字符。这很容易计算为右侧的最长序列、左侧的最长序列或跨越分割点的序列(这就是我们需要递归调用的最后两个值的原因)。这一切都可以在恒定时间内完成。我们还从两个递归调用中返回适当的值,以获取以最右边和最左边字符结尾的连续字符的长度。

这个递归最终得到 T(n) = T(n/2) + O(1),或者 O(lg n)

有很多边界情况需要处理,你需要弄清楚当递归“触底”时如何处理,但这应该足以让你编写代码。

【讨论】:

    【解决方案2】:

    如果您可以保证字母已排序,如您的示例所示,那么您可以使用二进制搜索来识别每个连续字母范围的末端。 每次二分查找都是 log(n);在最坏的情况下,你需要做 25 次才能找到所有边界,但我想“25 x constant x log(n)”仍然是 O(log(n))。

    如果您采用二分搜索方法,则可以巧妙地执行此操作 - 发现同一二分搜索中的连续测试何时返回相同的字母,因此假设作为最小范围大小,然后中止任何可能短于那个-但是您最好使用单独的搜索对其进行编码。或者最好只采用 O(n) 扫描解决方案:你真的需要这样做 O(log(n)) 吗?

    【讨论】:

    • 我不认为采访提到了一个排序字符串,就像我给出的例子一样,但这似乎是最可行的方法。
    【解决方案3】:

    没有办法在小于O(n) 的时间内找到最常见的字母,因为如果不检查字符串中的每个字符,您将无法确定该信息!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-22
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      • 2016-01-16
      • 2011-11-29
      • 2015-10-08
      • 1970-01-01
      相关资源
      最近更新 更多