标签:sts efi uil cte add ase rom from ++
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.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
标签:sts efi uil cte add ase rom from ++
原文地址:https://www.cnblogs.com/taste-it-own-it-love-it/p/10739691.html