竞争 - 最大字符数的算法

时间:2018-04-18 11:24:55

标签: algorithm performance

我试图解决这个挑战一些竞争激烈的网站。这是desc:

给定一个字符串,如果一个字符有两个相邻的字母,它们严格地小于它自己,那么该字符被认为是优越的。我们根据字母表中的位置比较字符。

更正式地说,如果一个角色存在于第(i + 1)个位置和第(i-1)个位置,并且第i个位置的角色严格大于第i个位置,则第i个位置的角色是优越的。 (i + 1)和第(i-1)个位置的角色。

考虑到小写英文字母的频率,使用所有这些字符形成一个字符串,以便结果字符串具有最大数量的高级字符。您需要打印最多数量的高级角色。

完成函数maximumSuperiorCharacters,它接受一个表示英文字母频率的整数数组,并返回一个表示最大字符数的整数。

0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0我们有两个es,一个l,一个s,没有其他字母。例如,我们可以形成一个具有一个高级字符的字符串。还可以表明这是可以存在的最高字符数。因此,答案是1.还有许多其他字符排列形成一个具有最大优良特征的字符串。

这是我到目前为止所做的事情

int maximumSuperiorCharacters(int[] Q)
{
  int R = 0;
  for (int V : Q) R += V;
  return --R / 2;
}

2 个答案:

答案 0 :(得分:3)

你可以在O(N)贪婪地做到这一点。高级字母的最大数量可以是M = floor((N-1)/2).从最大的字母开始,然后向下M字母。假设你在等级L结束了。计算0..L-1级别的字母数量,将其称为S(0,L-1)。 然后,您需要减少从L级到S(0,L-1)-1的字母数量,然后就完成了。

这里我提供了一个实现:

int maxsup(const vector<int>& charsCount) {
    const int length = accumulate(charsCount.cbegin(), charsCount.cend(), 0);
    const int optMaxSup = (length - 1) / 2;

    int charsUpToLimitLevelCount = 0;
    int limitLevel = 0;
    for (; charsUpToLimitLevelCount <= length - optMaxSup && limitLevel < (int)charsCount.size(); ++limitLevel) {
        charsUpToLimitLevelCount += charsCount[limitLevel];
    }
    const int supAtLimitLevel = optMaxSup + charsUpToLimitLevelCount - length;
    charsUpToLimitLevelCount -= charsCount[--limitLevel];

    const int matchedSupCount = min(supAtLimitLevel, max(charsUpToLimitLevelCount - 1, 0));
    return optMaxSup - (supAtLimitLevel - matchedSupCount);
}


int main() {
    cout << maxsup({ 0,0,0,0,0 }) << endl;
    cout << maxsup({ 0,0,0,0,1 }) << endl;
    cout << maxsup({ 0,0,0,2,1 }) << endl;
    cout << maxsup({ 15,7,0,0,0 }) << endl;
    cout << maxsup({ 5,4,3,2,1 }) << endl; // aaaaabbbbcccdde -> abacacacadbdbeb - 7
                                           //                     1 2 3 4 5 6 7
}

输出结果为:

  

0
  0
  1
  7
  7

Live.

答案 1 :(得分:1)

static long maximumSuperiorCharacters(int[] freq) {
    final int length = Arrays.stream(freq).sum();
    final int optMaxSup = (length - 1) / 2;

    int charsUpToLimitLevelCount = 0;
    int limitLevel = 0;
    for (; charsUpToLimitLevelCount <= length - optMaxSup && limitLevel < freq.length; ++limitLevel) {
        charsUpToLimitLevelCount += freq[limitLevel];
    }
    final int supAtLimitLevel = optMaxSup + charsUpToLimitLevelCount - length;
    charsUpToLimitLevelCount -= freq[--limitLevel];

    final int matchedSupCount = Math.min(supAtLimitLevel, Math.max(charsUpToLimitLevelCount - 1, 0));
    return optMaxSup - (supAtLimitLevel - matchedSupCount);

}