字符串中的重复字符是否可以在 O(n) 中识别和量化



此评论表明,对于此问题,我的O(n log n(解决方案有一个O(n(替代方案:

给定string str("helloWorld")预期输出为:

l = 3
o = 2

我的解决方案是这样做:

sort(begin(str), end(str));
for(auto start = adjacent_find(cbegin(str), cend(str)), finish = upper_bound(start, cend(str), *start); start != cend(str); start = adjacent_find(finish, cend(str)), finish = upper_bound(start, cend(str), *start)) {
   cout << *start << " = " << distance(start, finish) << endl;
}

这显然受到str排序的限制.我认为这需要一个桶排序解决方案?我缺少什么更聪明

的吗?

这是一种方法,即 O(N( 以维护每个可能的char值的存储为代价。

#include <string>
#include <limits.h> // for CHAR_MIN and CHAR_MAX. Old habits die hard.
int main()
{
    std::string s("Hello World");        
    int storage[CHAR_MAX - CHAR_MIN + 1] = {};
    for (auto c : s){
        ++storage[c - CHAR_MIN];
    }
    for (int c = CHAR_MIN; c <= CHAR_MAX; ++c){
        if (storage[c - CHAR_MIN] > 1){
            std::cout << (char)c << " " << storage[c - CHAR_MIN] << "n";
        }
    }    
}

这种便携式解决方案由于char可以signedunsigned而变得复杂。

以下是

@bathsheba提到的内容,并进行了@Holt改进:

#include <string>
#include <climits>
#include <iostream>
void show_dup(const std::string& str) {
    const int sz = CHAR_MAX - CHAR_MIN + 1;
    int all_chars[sz] = { 0 };
    // O(N), N - the length of input string
    for(char c : str) {
        int idx = (int)c;
        all_chars[idx]++;
    }
    // O(sz) - constant. For ASCII char it will be 256
    for(int i = 0; i < sz; i++) {
        if (all_chars[i] > 1) {
            std::cout << (char)i << " = " << all_chars[i] << std::endl;
        }
    }
}
int main()
{
  std::string str("helloWorld");
  show_dup(str);
}

最新更新