926. Flip String to Monotone Increasing**
https://leetcode.com/problems/flip-string-to-monotone-increasing/
题目描述
A string of '0’s and '1’s is monotone increasing if it consists of some number of '0’s (possibly 0), followed by some number of '1’s (also possibly 0.)
We are given a string S of '0’s and '1’s, and we may flip any ‘0’ to a ‘1’ or a ‘1’ to a ‘0’.
Return the minimum number of flips to make S monotone increasing.
Example 1:
Input: "00110"
Output: 1
Explanation: We flip the last digit to get 00111.
Example 2:
Input: "010110"
Output: 2
Explanation: We flip to get 011111, or alternatively 000111.
Example 3:
Input: "00011000"
Output: 2
Explanation: We flip to get 00000000.
Note:
1 <= S.length <= 20000
S
only consists of'0'
and'1'
characters.
C++ 实现 1
class Solution {
public:
int minFlipsMonoIncr(string S) {
int n = S.size();
int res = 0;
int num_zeros = 0, num_ones = 0;
for (int i = 0; i < n; ++ i) {
num_zeros += S[i] == '0' ? 1 : 0;
num_ones += S[i] == '1' ? 1 : 0;
}
res = std::min(num_zeros, num_ones);
if (res == 0) return res;
int change = 0;
for (int i = 0; i < n; ++ i) {
if (S[i] == '1') {
int zeros_left = n - i - (num_ones - change);
res = std::min(res, zeros_left + change); // S[i] 不变
change += 1; // S[i] 改变
}
}
return res;
}
};
C++ 实现 2
使用 DP 实现. 关于这道题, 我比较高兴的是自己可以有意识的从 DP 的思路出发去考虑问题. 唯一的遗憾是没有想清楚 🤣. 参看 C++ one-pass DP solution, 0ms O(n) | O(1), one line, with explaination 用 DP 的思路求解, 解释的很详细.
具体说来:
先考虑子问题已经求解好了, 即假设 S
变成 mono increasing 的需要经过最少 num_flip
次翻转, 该字符串中有 num_ones
个 '1'
.
之后, 当有一个新的字符 ch
加入到 S
后面时, 问题变成了如何在子问题已经得到求解的基础上来更新 num_flip
以及 num_ones
. 分为两种情况:
-
如果加入的字符为
1
, 那么无需增加额外的 flip,1
直接加入到S
的后面即可. -
如果加入的字符为
0
, 情况有一些复杂, 此时我们有两个选择:a.
S
经过num_flip
次翻转后, 再将0
变为1
;
b. 或者将S
中的num_ones
全部翻转为0
, 这样新的ch = '0'
可以直接加入到S
后面;
最终我们只需要计算 num_flip = std::min(num_flip + 1, num_ones)
.
class Solution {
public:
int minFlipsMonoIncr(string S) {
int num_flip = 0, num_ones = 0;
for (auto &s : S) {
if (s == '1') { // 新加入的字符为 1, 注意更新 num_ones
++ num_ones;
} else { // 新加入的字符为 0, 选择 a
++ num_flip;
}
// 当 s 为 0 时, 此时就是在对比选择 a 和选择 b
num_flip = std::min(num_flip, num_ones);
}
return num_flip;
}
};