同步操作将从 doocs/leetcode 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
给你一个字符串 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
的个数。
遍历字符串 $s$:
如果当前字符为 b
,此时不影响平衡串的最小删除次数,那么 $dp[i]=dp[i-1]$,并且累加 $b$。
如果当前字符为 a
,此时,要想达到平衡,要么把前面的所有 b
都删掉,操作次数为 $b$;要么把当前的 a
删除,操作次数为 $dp[i-1]+1$。取两者的最小值即可。即 $dp[i]=\min(b,dp[i-1]+1)$。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
我们发现 $dp[i]$ 只与 $dp[i-1]$ 有关,因此可以使用变量 ans
来代替数组 dp
。空间复杂度优化为 $O(1)$。
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
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。