Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leetcode 926. Flip String to Monotone Increasing / 1653. Minimum Deletions to Make String Balanced #184

Open
Woodyiiiiiii opened this issue Jan 17, 2023 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

Woodyiiiiiii commented Jan 17, 2023

A binary string is monotone increasing if it consists of some number of 0's (possibly none), followed by some number of 1's (also possibly none).

You are given a binary string s. You can flip s[i] changing it from 0 to 1 or from 1 to 0.

Return the minimum number of flips to make s monotone increasing.

Example 1:

Input: s = "00110"
Output: 1
Explanation: We flip the last digit to get 00111.

Example 2:

Input: s = "010110"
Output: 2
Explanation: We flip to get 011111, or alternatively 000111.

Example 3:

Input: s = "00011000"
Output: 2
Explanation: We flip to get 00000000.

这道题很有意思,有两种解法。

第一种解法: 观察规律,利用前缀和思想

这种方法很容易想到。首先易得肯定是在O(n)时间复杂度的情况下找到答案,又是二元字符串,所以很可能用到前缀和的思想,得知任意位置前面或后面0和1的个数。

然后从所有结果出发,为达到这些结果,[1111..1]到[0000..0],总共n种结果,而这所有结果之间又有联系,很容易找到达成这些结果需要翻转的个数,也就是知道所有可能的答案,找到最小值即可。说明最大/最小值不一定用二分,这里是遍历所有情况

不要直接从题目当前所给的初始字符串出发,否则很难构建所有可能性。要想到前缀和的思想,利用遍历时变化

class Solution {
    public int minFlipsMonoIncr(String s) {
        int zeroCnt = 0;
        for (char c : s.toCharArray()) {
            if (c == '0') {
                ++zeroCnt;
            }
        }
        int ans = zeroCnt, cnt = ans;
        for (int i = 0; i < s.length(); ++i) {
            char c = s.charAt(i);
            if (c == '0') {
                cnt--;
            } else {
                cnt++;
            }
            ans = Math.min(ans, cnt);
        }
        return ans;
    }
}

第二种解法: 动态规划

即然字符串是monotone increasing,那么子字符串也是monotone increasing。所以为了使[0,i]满足条件,就要先使[0,i-1]达成条件。这就暗示了DP思想。

设dp[i]是[0,i)子字符串中需要flip的最小次数,base条件是dp[0]=0。

这种解法来自官方讲解,如下链接地址,很清晰。思路是这样的:从左到右,在满足题目条件的子字符串最后加上1或者0,会有不同的结果,有联系。如果是1,因为字符串已经符合条件了,所以不变;如果是0,则要考虑是否翻转的可能,若翻转,则结果是前面的结果+1,否则要将字符串中所有的1变为0,两者取最小。

这里的出发点直接是dp[i]=最小值。把结果作为DP缓存,从而推导递进函数,应该是普遍的DP思路。强

class Solution {
    public int minFlipsMonoIncr(String s) {
        int ans = 0, num = 0;
        for (int i = 0; i < s.length(); ++i) {
            if (s.charAt(i) == '0') {
                ans = Math.min(num, ans + 1);
            } else {
                ++num;
            }
        }
        return ans;
    }
}

总结:

  • 第一种方法是枚举所有可能。找到所有能够满足题目条件的字符串,然后找到能够达成的方法要求,然后比较最小
  • 第二种方法是动态规划。确定无后效性后,然后找到dp元素的定义,然后定义dp元素间的推导公式


类似题目:

class Solution {
    public int minimumDeletions(String s) {
        int aCnt = 0, bCnt = 0;
        for (char c : s.toCharArray()) {
            if (c == 'a') {
                aCnt++;
            } else if (c == 'b') {
                bCnt++;
            }
        }
        int n = s.length(), ans = n;
        ans = Math.min(aCnt, bCnt);
        int aCnt2 = 0, bCnt2 = 0;
        for (char c : s.toCharArray()) {
            if (c == 'a') {
                aCnt2++;
                aCnt--;
            } else if (c == 'b') {
                bCnt2++;
                bCnt--;
            }
            ans = Math.min(ans, bCnt2 + aCnt);
        }
        return ans;
    }
}

Or:

class Solution {
    public int minimumDeletions(String s) {
        int ans = 0, n = s.length();
        int bCnt = 0;
        for (char c : s.toCharArray()) {
            if (c == 'a') {
                ans = Math.min(bCnt, ans + 1);
            } else {
                bCnt++;
            }
        }
        return ans;
    }
}
@Woodyiiiiiii Woodyiiiiiii changed the title Leetcode 926. Flip String to Monotone Increasing Leetcode 926. Flip String to Monotone Increasing / 1653. Minimum Deletions to Make String Balanced Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant