友情支持
如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜
有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。
公众号的微信号是: jikerizhi 。因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。 |
926. 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.
思路分析
如果下标 i 处的字符是 0,则只有当下标 i−1 处的字符是 0 时才符合单调递增;如果下标 i 处的字符是 1,则下标 i−1 处的字符是 0 或 1 都符合单调递增,此时为了将翻转次数最小化,应分别考虑下标 i−1 处的字符是 0 和 1 的情况下需要的翻转次数,取两者的最小值。
对于 0≤i<n,用 dp[i][0] 和 dp[i][1] 分别表示下标 i 处的字符为 0 和 1 的情况下使得 s[0..i] 单调递增的最小翻转次数。
-
一刷
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* @author D瓜哥 · https://www.diguage.com
* @since 2024-09-24 17:54:37
*/
public int minFlipsMonoIncr(String s) {
// 1. 确定 dp 数组(dp table)以及下标的含义
// 对于 0≤i<n,用 dp[i][0] 和 dp[i][1] 分别表示下标 i 处的
// 字符为 0 和 1 的情况下使得 s[0..i] 单调递增的最小翻转次数。
// 如果下标 i 处的字符是 0,则只有当下标 i−1 处的字符是 0 时才符合
// 单调递增;如果下标 i 处的字符是 1,则下标 i−1 处的字符是 0 或 1
// 都符合单调递增,此时为了将翻转次数最小化,应分别考虑下标 i−1 处的
// 字符是 0 和 1 的情况下需要的翻转次数,取两者的最小值。
int[][] dp = new int[s.length() + 1][2];
// 3. dp 数组如何初始化
dp[0][0] = 0;
dp[0][1] = 0;
// 4. 确定遍历顺序
for (int i = 1; i <= s.length(); i++) {
boolean isZero = s.charAt(i - 1) == '0';
// 2. 确定递推公式
dp[i][0] = dp[i - 1][0] + (!isZero ? 1 : 0);
dp[i][1] = Math.min(dp[i - 1][0], dp[i - 1][1]) + (isZero ? 1 : 0);
}
return Math.min(dp[s.length()][0], dp[s.length()][1]);
}