1. 程式人生 > >LeetCode 926. 將字串翻轉到單調遞增 遞迴實現動態規劃 兩種解法

LeetCode 926. 將字串翻轉到單調遞增 遞迴實現動態規劃 兩種解法

這個題做了一個多小時,考慮複雜了。

  • 開始推動規沒有推出來,然後找到一個遞推關係:從左往右,如果是0,則不需要變動;如果是1,則有兩種選擇(1)將1變為0(2)將1後面的所有數字變為1,這兩種方法中的變動數字最小的方法就是最佳方法,然後依次遞推,很容易寫出遞迴程式。但是這裡面存在問題,如果直接計數1後面0的個數會超時;開陣列提前儲存會爆記憶體。所以在其中採用動規,在呼叫返回時記錄0的數量。(這裡的動規用for迴圈寫也可以)
  • 另一種方法是看兩個數字間的縫隙的左右兩側的需要變動的0和1的數量,加和最小為最優。

題目

java程式碼如下:

  • 遞迴實現動態規劃
class Solution {
    public int count_0;

    public Solution(){
        
        count_0 = 0;
    }

    public int minFlipsMonoIncr(String S) {

        if(S.length() <= 0) return 0;
        int min = 999;
        if(S.charAt(0) == '0'){
            min = minFlipsMonoIncr(S.substring(1));
            count_0++
; } else{ min = minFlipsMonoIncr(S.substring(1)) + 1; if(min > count_0) min = count_0; } return min; } }
  • 另一種解法
class Solution {
    public int minFlipsMonoIncr(String S) {

        int[] count_0 = new int[S.length() + 5];
        int
[] count_1 = new int[S.length() + 5]; count_0[S.length()] = 0; count_1[0] = 0; for (int i = S.length() - 1, sum = 0; i >= 0; i--) { if (S.charAt(i) == '0') { count_0[i] = ++sum; } else { count_0[i] = sum; } } for (int i = 1, sum = 0; i <= S.length(); i++) { if (S.charAt(i - 1) == '1') { count_1[i] = ++sum; } else { count_1[i] = sum; } } int min = 99999; for (int i = 0; i <= S.length(); i++) { if (count_0[i] + count_1[i] < min) { min = count_0[i] + count_1[i]; } } return min; } }