Leetcode 動態規劃 刷題筆記

二維數組

1月24日

115 💗 不一樣的子序列 💗 HARD

構建二維動態數組 java

public class Solution {
    public int numDistinct(String s, String t) {
        if(s.length()==0 || t.length()==0 || t.length()>s.length()) return 0;
        int[][] dp = new int[t.length()+1][s.length()+1];
        char[] s_arr = s.toCharArray();
        char[] t_arr = t.toCharArray();
        for(int i=0; i<=s.length(); i++) dp[0][i]=1;
        for(int i=1; i<=t_arr.length; i++){
            dp[i][0] = 0;
            for(int j=1; j<=s_arr.length; j++){
                dp[i][j] = dp[i][j-1];
                if(s_arr[j-1]==t_arr[i-1]) dp[i][j]+=dp[i-1][j-1];
            }
        }
        return dp[t.length()][s.length()];
    }
}
複製代碼

97 💗 交錯字符串 💗 HARD

創建二維dp數組,縱座標str1,橫座標str2。遍歷到dp[i][j]時若是選str2則dp[i][j+1]=1,若是選的是str2則dp[i+1][j]=1,若是都不行,則不作任何改變數組

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        if(s1.length()+s2.length() != s3.length()) return false;
        int[][] dp = new int[s1.length()+1][s2.length()+1];
        char[] s1_arr = s1.toCharArray();
        char[] s2_arr = s2.toCharArray();
        char[] s3_arr = s3.toCharArray();
        dp[0][0] = 1;
        for(int i=0; i<=s1.length(); i++){
            for(int j=0; j<=s2.length(); j++){
                if(i==s1.length() && j==s2.length()) continue;
                else if(i==s1.length()){
                    if(dp[i][j]==1&&s2_arr[j]==s3_arr[i+j]) dp[i][j+1]=1;
                }
                else if(j==s2.length()){
                    if(dp[i][j]==1&&s1_arr[i]==s3_arr[i+j]) dp[i+1][j]=1;
                }else{
                    if(dp[i][j]==1&&s2_arr[j]==s3_arr[i+j]) dp[i][j+1]=1;
                    if(dp[i][j]==1&&s1_arr[i]==s3_arr[i+j]) dp[i+1][j]=1;
                }
            }
        }
        if(dp[s1.length()][s2.length()]==1){
            return true;
        }else{
            return false;
        }
    }
}
複製代碼

174 💗 地下城遊戲 💗 HARD

倒序DP,每個點記錄最少的負血量,每一個點的值取決於另外右邊和下方的值spa

class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        int n = dungeon.length;
        int m = dungeon[0].length;
        int[][] dp = new int[n][m];
        dp[n-1][m-1] = dungeon[n-1][m-1];
        if(dp[n-1][m-1]>0) dp[n-1][m-1]=0;
        for(int i=n-1; i>=0; i--){
            for(int j=m-1; j>=0; j--){
                if(i==n-1 && j==m-1) continue;
                if(i==n-1){
                    if(dungeon[i][j]+dp[i][j+1]<0){
                        dp[i][j]=dungeon[i][j]+dp[i][j+1];
                    }else{
                        dp[i][j]=0;
                    }
                }else if(j==m-1){
                    if(dungeon[i][j]+dp[i+1][j]<0){
                        dp[i][j]=dungeon[i][j]+dp[i+1][j];
                    }else{
                        dp[i][j]=0;
                    }
                }else{
                    dp[i][j] = dungeon[i][j] + Math.max(dp[i][j+1],dp[i+1][j]);
                    if(dp[i][j]>0) dp[i][j]=0;
                }
            }
        }
        if(dp[0][0]>0){
            return 1;
        }else{
            return -dp[0][0]+1;
        }
    }
}
複製代碼

120 💗 楊輝三角最小路徑 💗 MID

又是一道倒序dp,能夠直接在原list上操做。code

  • 🌟ArrayList操做:
  • 2D取值: list.get(index).get(index)
  • 尺寸: list.size()
  • 2D賦值: list.get(index).put(index, value)

198 💗 打家劫舍 💗 EASY

先分析狀態,有打劫和不打劫兩種,cdn

  • 1.若是打劫則把當前打劫的和剛纔房子沒被打劫前的錢數相加
  • 2.若是沒打劫,則取前一個房子打劫和沒打劫的最大值

213 💗 打家劫舍II 💗 MID

跟version 1幾乎同樣,可是首尾相連,須要單獨考慮,咱們把搶第一家和不搶第一家分紅兩種狀況dp,最後求最大值。blog

139 💗 單詞拆分 💗 MID

若是i到j是valid words並且i以前是true,則0到j都是true遊戲

相關文章
相關標籤/搜索