给你一个字符串 s
,它仅包含字符 'a'
和 'b'
。
你可以删除 s
中任意数目的字符,使得 s
平衡 。我们称 s
平衡的 当不存在下标对 (i,j)
满足 i < j
且 s[i] = 'b'
同时 s[j]= 'a'
。
请你返回使 s
平衡 的 最少 删除次数。
示例 1:
输入:s = "aababbab" 输出:2 解释:你可以选择以下任意一种方案: 下标从 0 开始,删除第 2 和第 6 个字符("aababbab" -> "aaabbb"), 下标从 0 开始,删除第 3 和第 6 个字符("aababbab" -> "aabbbb")。
示例 2:
输入:s = "bbaaaaabb" 输出:2 解释:唯一的最优解是删除最前面两个字符。
提示:
1 <= s.length <= 105
s[i]
要么是'a'
要么是'b'
。
方法一:动态规划
定义 dp[i]
表示字符串 s[0..i)
达到平衡时,需要删除的最少字符数,答案为 dp[n]
。用变量 b
的个数。
遍历字符串
如果当前字符为 b
,此时不影响平衡串的最小删除次数,那么
如果当前字符为 a
,此时,要想达到平衡,要么把前面的所有 b
都删掉,操作次数为 a
删除,操作次数为
时间复杂度
我们发现 ans
来代替数组 dp
。空间复杂度优化为
class Solution:
def minimumDeletions(self, s: str) -> int:
n = len(s)
dp = [0] * (n + 1)
b = 0
for i, c in enumerate(s, 1):
if c == 'b':
dp[i] = dp[i - 1]
b += 1
else:
dp[i] = min(dp[i - 1] + 1, b)
return dp[n]
class Solution:
def minimumDeletions(self, s: str) -> int:
ans = b = 0
for c in s:
if c == 'b':
b += 1
else:
ans = min(b, ans + 1)
return ans
class Solution {
public int minimumDeletions(String s) {
int n = s.length();
int[] dp = new int[n + 1];
int b = 0;
for (int i = 0; i < n; ++i) {
if (s.charAt(i) == 'b') {
dp[i + 1] = dp[i];
++b;
} else {
dp[i + 1] = Math.min(dp[i] + 1, b);
}
}
return dp[n];
}
}
class Solution {
public int minimumDeletions(String s) {
int ans = 0, b = 0;
for (char c : s.toCharArray()) {
if (c == 'b') {
++b;
} else {
ans = Math.min(b, ans + 1);
}
}
return ans;
}
}
class Solution {
public:
int minimumDeletions(string s) {
int n = s.size();
vector<int> dp(n + 1);
int b = 0;
for (int i = 0; i < n; ++i) {
if (s[i] == 'b') {
dp[i + 1] = dp[i];
++b;
} else {
dp[i + 1] = min(dp[i] + 1, b);
}
}
return dp[n];
}
};
class Solution {
public:
int minimumDeletions(string s) {
int ans = 0, b = 0;
for (char c : s) {
if (c == 'b') {
++b;
} else {
ans = min(b, ans + 1);
}
}
return ans;
}
};
func minimumDeletions(s string) int {
n := len(s)
dp := make([]int, n+1)
b := 0
for i, c := range s {
if c == 'b' {
b++
dp[i+1] = dp[i]
} else {
dp[i+1] = min(dp[i]+1, b)
}
}
return dp[n]
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func minimumDeletions(s string) int {
ans, b := 0, 0
for _, c := range s {
if c == 'b' {
b++
} else {
ans = min(b, ans+1)
}
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}