Files
2020-11-28 14:37:19 +08:00

90 lines
3.4 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [1653. Minimum Deletions to Make String Balanced](https://leetcode.com/problems/minimum-deletions-to-make-string-balanced/)
## 题目
You are given a string `s` consisting only of characters `'a'` and `'b'`.
You can delete any number of characters in `s` to make `s` **balanced**. `s` is **balanced** if there is no pair of indices `(i,j)` such that `i < j` and `s[i] = 'b'` and `s[j]= 'a'`.
Return *the **minimum** number of deletions needed to make* `s` ***balanced***.
**Example 1:**
```
Input: s = "aababbab"
Output: 2
Explanation: You can either:
Delete the characters at 0-indexed positions 2 and 6 ("aababbab" -> "aaabbb"), or
Delete the characters at 0-indexed positions 3 and 6 ("aababbab" -> "aabbbb").
```
**Example 2:**
```
Input: s = "bbaaaaabb"
Output: 2
Explanation: The only solution is to delete the first two characters.
```
**Constraints:**
- `1 <= s.length <= 105`
- `s[i]` is `'a'` or `'b'`.
## 题目大意
给你一个字符串 s 它仅包含字符 'a' 和 'b' 。你可以删除 s 中任意数目的字符使得 s 平衡 。我们称 s 平衡的 当不存在下标对 (i,j) 满足 i < j  s[i] = 'b' 同时 s[j]= 'a' 请你返回使 s 平衡  最少 删除次数
## 解题思路
- 给定一个字符串要求删除最少次数使得字母 a 都排在字母 b 的前面
- 很容易想到的一个解题思路是 DP定义 `dp[i]` 为字符串下标 [ 0, i ] 这个区间内使得字符串平衡的最少删除次数 `s[i] == 'a'` 的时候 2 种情况一种是 `s[i]` 前面全是 `[aa……aa]` 的情况这个时候只需要把其中的所有的字母 `b` 删除即可还有一种情况是 `s[i]` 前面有字母 `a` 也有字母 `b` `[aaa……abb……b]`这种情况就需要考虑 `dp[i-1]` 当前字母是 `a`那么肯定要删除字母 `a`来维持前面有一段字母 `b` 的情况 `s[i] == 'b'` 的时候不管是 `[aa……aa]` 这种情况还是 `[aaa……abb……b]` 这种情况当前字母 `b` 都可以直接附加在后面也能保证整个字符串是平衡的所以状态转移方程为 `dp[i+1] = min(dp[i] + 1, bCount), s[i] == 'a'``dp[i+1] = dp[i], s[i] == 'b'`最终答案存在 `dp[n]` 由于前后项的递推关系中只用到一次前一项所以我们还可以优化一下空间用一个变量保存前一项的结果优化以后的代码见解法一
- 这一题还有一个模拟的思路题目要求找到最小删除字数那么就是要找到一个临界点”,在这个临界点的左边删除所有的字母 b在这个临界点的右边删除所有的字母 a在所有的临界点中找到删除最少的次数代码实现见解法二
## 代码
```go
package leetcode
// 解法一 DP
func minimumDeletions(s string) int {
prev, res, bCount := 0, 0, 0
for _, c := range s {
if c == 'a' {
res = min(prev+1, bCount)
prev = res
} else {
bCount++
}
}
return res
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
// 解法二 模拟
func minimumDeletions1(s string) int {
aCount, bCount, res := 0, 0, 0
for i := 0; i < len(s); i++ {
if s[i] == 'a' {
aCount++
}
}
res = aCount
for i := 0; i < len(s); i++ {
if s[i] == 'a' {
aCount--
} else {
bCount++
}
res = min(res, aCount+bCount)
}
return res
}
```