Problem
You are given a string s.
A string t is called good if all characters of t occur the same number of times.
You can perform the following operations any number of times:
- Delete a character from
s. - Insert a character in
s. - Change a character in
sto its next letter in the alphabet.
Note that you cannot change 'z' to 'a' using the third operation.
Return the minimum number of operations required to make s good.
https://leetcode.com/problems/minimum-operations-to-make-character-frequencies-equal/
Example 1:
Input:
s = "acab"
Output:1
Explanation:
We can make s good by deleting one occurrence of character'a'.
Example 2:
Input:
s = "wddw"
Output:0
Explanation:
We do not need to perform any operations since s is initially good.
Example 3:
Input:
s = "aaabc"
Output:2
Explanation:
We can make s good by applying these operations:
- Change one occurrence of
'a'to'b'- Insert one occurrence of
'c'into s
Constraints:
3 <= s.length <= 2 * 10⁴scontains only lowercase English letters.
Test Cases
1 | class Solution: |
1 | import pytest |
Thoughts
可以进行的三个操作:
- 删除任意字符。
- 插入任意字符。
- 把任意字符替换成其字典序的下一个字符(如
'a'换成'b')。显然对两个或更多相连的字符做此操作没意义(如'a'换成'b','b'再换成'c'),可以用删除第一个 + 插入最后一个替代。
开始一直想怎么计算出最终 good 状态时,每个字符的个数(记为目标值 t),或者在推导最少操作次数的过程中能自适应更新这个值,未果。只好直接暴力(brute force)枚举所有可能的 t。显然 t 最小为 0,最大不会超过 s 中的最大词频。中间的任何一个值都是有可能的。问题就转变为对于指定的 t,计算出最终词频全为 t(或者 0)的最少操作次数。
首先统计出 s 中每个字符的词频。记 i(1 ≤ i ≤ 26)表示按字典序的第 i 个小写字母(简称字符 i),记 fᵢ 为字符 i 在 s 中的词频。
记 ops(i) 表示把前 i 个字符的词频都调成 t 所需的最少操作次数,同时记录 del(i) 表示当 ops(i) 最优时,第 i 个字符被删除的个数(用于进行操作 3)。
如果 fᵢ ≥ t,那就删掉 fᵢ - t 个字符 i 即可,同时 del(i) = fᵢ - t。
如果 fᵢ < t,那么有两个选择,一个是把 fᵢ 个字符 i 全部删光(同时 del(i) = fᵢ),另一个是插入 ins = t - fᵢ 个字符 i。
插入动作需要考虑是否可以通过操作 3 替代掉一部分,以减少操作次数。这里又有两个选择。
如果前一个字符做了一些删除操作(del(i - 1) > 0),可以把其中的一些改成操作 3,剩余的插入次数为 max{0, ins - del(i - 1)}。
另一个选择是把前一个字符全部删除(共 fᵢ₋₁ 次),把其中一些改成操作 3,剩余的插入次数为 ins' = max{0, ins - fᵢ₋₁}。总的操作次数相当于在 ops(i - 2) 的基础上,增加 fᵢ₋₁ + ins' 次。
总结下来,ops(i) 和 del(i) 的转移方程为:
其中 ops 只需要保留前两个值,del 只需要保留前一个值,占用 O(1) 空间。
设 s 中各不相同的字符共 k 个(按题目限定最多为 26,也可以认为是常数),最大词频为 F = O(n),则时间复杂度 O(k * n),空间复杂度 O(k)。
Code
1 | class Solution: |