题目描述
定义字符串完全由 ‘A’ 和 ‘B’组成,当然也可以全是’A’或全是’B’。如果字符串从前往后都是以字典序排列的,那么我们称之为严格递增字符串。
给出一个字符串s,允许修改字符串中的任意字符,即可以将任何的’A’修改成’B’,也可以将任何的’B’修改成’A’,
求可以使s满足严格递增的最小修改次数。
0 < s的长度 < 100000。
输入描述
输入一个字符串: “AABBA”
输出描述
输出:1
用例
输入 | AABBA |
输出 | 1 |
说明 | 修改最后一位得到AABBB。 |
解题思路分析
这道题的目的是将一个由字符 'A' 和 'B' 组成的字符串转换为一个严格递增的字符串,即所有的 'A' 都应该出现在所有的 'B' 之前。我们可以通过计算需要修改的最小次数来实现这一转换。
步骤分析:
-
问题描述简化:
- 对于一个字符串,如果在某一位置存在一个 'B',且在它之前存在一个 'A',这就会导致不是严格递增的情况。我们需要决定要么将这些 'A' 修改成 'B',要么将这些 'B' 修改成 'A'。
-
思路:
- 我们可以从左到右遍历字符串,同时记录每个位置左侧的 'A' 的数量以及右侧的 'B' 的数量。然后对于每一个位置,计算将左侧所有 'A' 转换为 'B' 和右侧所有 'B' 转换为 'A' 的总成本,取其中最小的值作为结果。
-
步骤:
- 从左到右遍历字符串,记录每个位置前面有多少个 'A'。
- 从右到左遍历字符串,记录每个位置后面有多少个 'B'。
- 对于每一个位置,计算将左侧的 'A' 改为 'B' 或将右侧的 'B' 改为 'A' 的代价,选择最小的代价。
-
优化:
- 考虑时间复杂度为 O(n),因此适用于处理长度较长的字符串。
C++ 代码实现
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int minOperationsToStrictlyIncreasing(string s) {
int n = s.length();
vector<int> leftA(n, 0), rightB(n, 0);
// 计算左侧的A的数量
for (int i = 1; i < n; ++i) {
leftA[i] = leftA[i - 1] + (s[i - 1] == 'A' ? 1 : 0);
}
// 计算右侧的B的数量
for (int i = n - 2; i >= 0; --i) {
rightB[i] = rightB[i + 1] + (s[i + 1] == 'B' ? 1 : 0);
}
int minOps = min(rightB[0], leftA[n-1]); // 只修改全B或全A的情况
for (int i = 0; i < n; ++i) {
minOps = min(minOps, leftA[i] + rightB[i]);
}
return minOps;
}
int main() {
string s;
cin >> s;
cout << minOperationsToStrictlyIncreasing(s) << endl;
return 0;
}
Python 代码实现
def min_operations_to_strictly_increasing(s):
n = len(s)
left_a = [0] * n
right_b = [0] * n
# 计算左侧的A的数量
for i in range(1, n):
left_a[i] = left_a[i - 1] + (1 if s[i - 1] == 'A' else 0)
# 计算右侧的B的数量
for i in range(n - 2, -1, -1):
right_b[i] = right_b[i + 1] + (1 if s[i + 1] == 'B' else 0)
min_ops = min(right_b[0], left_a[-1]) # 只修改全B或全A的情况
for i in range(n):
min_ops = min(min_ops, left_a[i] + right_b[i])
return min_ops
if __name__ == "__main__":
s = input()
print(min_operations_to_strictly_increasing(s))
解题说明
-
左右计数:我们分别计算从左至右和从右至左的累计 'A' 和 'B' 的数量,从而能够在每个位置快速确定两侧的修改代价。
-
最小修改次数:对于每一个位置,我们都计算两侧的修改代价并选择最小值作为最终的答案。
-
时间复杂度:由于我们只需要两次遍历字符串,所以时间复杂度为 O(n),可以处理较长的字符串。
这个解法非常高效,能够在较大输入规模下迅速得出结果。