Flip String to Monotone Increasing LT926

Posted taste-it-own-it-love-it

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flip String to Monotone Increasing LT926相关的知识,希望对你有一定的参考价值。

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. 1 <= S.length <= 20000
  2. S only consists of ‘0‘ and ‘1‘ characters.

Idea 1. 由结果推算,if monotonic increasing string is composed of x zeros and (n-x) ones, based on the number of ones on the left and right side of str[x], the number of flips can be calculated as ones[x] + (n-x - (ones[n] - ones[x])), another example to use prefix sum to caculate ones.

flip from ‘1‘ -> ‘0‘ on the left: ones[x]

flip from ‘0‘ -> ‘1‘ on the right: n - x - (ones[n] - ones[x]) or scan the array from right to left

仔细corner case, 全部都是‘0‘ or ‘1‘ monotonic increasing string.

Time complexity: O(n)

Space complexity: O(n)

 1 class Solution {
 2     public int minFlipsMonoIncr(String S) {
 3         int n = S.length();
 4         int[] ones = new int[n+1];
 5         for(int i = 1; i <=n; ++i) {
 6             ones[i] = ones[i-1] + S.charAt(i-1) - ‘0‘;
 7         }
 8         
 9         int result = Integer.MAX_VALUE;
10         for(int i = 0; i <= n; ++i) {
11             result = Math.min(result, ones[i] + (n - i) - (ones[n] - ones[i]));
12         }
13         
14         return result;
15     }
16 }

Idea 1.b No need to build ones array, the number of ones can be computed while looping the array, just need the total number of ones in advance

Time complexity: O(n)

Space complexity: O(1)

 1 class Solution {
 2     public int minFlipsMonoIncr(String S) {
 3         int n = S.length();
 4         int totalOnes = 0;
 5         for(int i = 0; i < S.length(); ++i) {
 6             totalOnes += S.charAt(i) - ‘0‘;
 7         }
 8         int ones = 0;
 9         
10         int result = Integer.MAX_VALUE;
11         for(int i = 0; i <= n; ++i) {
12             if(i >= 1) {
13                 ones += S.charAt(i-1) - ‘0‘;
14             }
15             result = Math.min(result, ones + (n - i) - (totalOnes - ones)); 
16         }
17         
18         return result;
19     }
20 }

稍微简洁一点,把全身1的情况做初始值

 1 class Solution {
 2     public int minFlipsMonoIncr(String S) {
 3         int n = S.length();
 4         int totalOnes = 0;
 5         for(int i = 0; i < S.length(); ++i) {
 6             totalOnes += S.charAt(i) - ‘0‘;
 7         }
 8         int ones = 0;
 9         
10         int result = n - totalOnes;
11         for(int i = 1; i <= n; ++i) {
12             ones += S.charAt(i-1) - ‘0‘;
13             result = Math.min(result, ones + (n - i) - (totalOnes - ones)); 
14         }
15         
16         return result;
17     }
18 }

Idea 2. Dynamic programming, 网上看到的更赞的方法, let dp[i-1] be the minimum number of flips to make S.substring(0, i) is monotonic increasing, how to extend the solution for S.charAt(i)?

dp[i] = dp[i-1] if S.charAt(i) == ‘1‘, nothing needed, as it still satisfy monotonic increasing string.

dp[i] = Math.min(ones[i-1], dp[i-1] + 1), if S.chart(i) == ‘0‘ either flip all the previous ones to 0; or flip the current ‘0‘ to ‘1‘ since S.substring(0, i) is monotonice, add ‘1‘ still satisfies the conidtion. 

Time complexity: O(n)

Space complexity: O(n)

 1 class Solution {
 2     public int minFlipsMonoIncr(String S) {
 3         int n = S.length();
 4         int[] dp = new int[n+1];
 5         int ones = 0;
 6         for(int i = 1; i <= n; ++i) {
 7             if(S.charAt(i-1) == ‘1‘) {
 8                 dp[i] = dp[i-1];
 9                 ++ones;
10             }
11             else {
12                 dp[i] = Math.min(dp[i-1] + 1, ones);
13             }
14         }
15         
16         return dp[n];
17     }
18 }

Idea 2.b the above formula shows the current dp depends only on the previous number, the array dp[] is not needed

Time complexity: O(n)

Space complexity: O(1)

 1 class Solution {
 2     public int minFlipsMonoIncr(String S) {
 3         int n = S.length();
 4         int dp = 0;
 5         int ones = 0;
 6         for(int i = 1; i <= n; ++i) {
 7             if(S.charAt(i-1) == ‘1‘) {
 8                 ++ones;
 9             }
10             else {
11                 dp = Math.min(dp + 1, ones);
12             }
13         }
14         
15         return dp;
16     }
17 }

以上是关于Flip String to Monotone Increasing LT926的主要内容,如果未能解决你的问题,请参考以下文章

Flip String to Monotone Increasing LT926

leetcode 926. Flip String to Monotone Increasing

[LeetCode] 926. Flip String to Monotone Increasing 翻转字符串到单调递增

Flip Game

14:Flip Game

Buffer flip()方法用法