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游戏

相关文章
相关标签/搜索