我希望通过执行最少数量的操作来均衡字符串中字符的频率。这里有一个操作是"一次删除一个字符"。 字符串由小写英文字母组成。
E.g。给定字符串" abcdab" ,在这里我可以删除一个' a'和一个'因此,将需要2个操作,然后每个字符的频率相等。
此外,我可以完全删除字符,例如。 ' aaaabbbc' 在此我可以删除一个' c'和一个'使频率相等。
我无法找到逻辑。任何人都可以建议算法吗?
答案 0 :(得分:1)
让我先描述一个二次解,然后我们将它设为O(n log n)
将您的字符串转换为频率列表:
4, 3, 1
然后,观察所有角色将共享的最终频率将等于现有频率之一。换句话说,最后频率将是4,3或1.在循环中尝试每个频率。修正频率后,很容易计算使所有字符具有该频率或零的步骤数。这将是:
res = BIG;
for (int idxOfFreqIWant = 0; idxOfFreqIWant < n; ++ idxOfFreqIWant) {
int cur = 0;
for (int i = 0; i < n; ++ i) {
// if element occurs >= the freq, we remove characters to make it equal to freq
if (a[i] >= a[idxOfFreqIWant]) cur += a[i] - a[idxOfFreqIWant];
// otherwise we have to remove all occurences
else cur += a[i];
}
if (cur < res) res = cur;
}
现在,这显然是二次方的。您可以将它设为O(n log n),我只会描述高级概念:您按降序对所有频率进行排序,从左到右迭代,并保持到目前为止看到的频率的总和和计数。现在,当您修复频率时,您知道具有较高频率的所有字符的总和和计数,以及具有较低频率的所有字符的总和和计数,您可以计算cur
而不迭代所有元素,因此在恒定时间内进行一次更新。总复杂度为O(n log n)
以排序+ O(n)
来进行传递。