二维数组
1月24日
115 💗 不同的子序列 💗 HARD
构建二维动态数组

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,每一个点记录最少的负血量,每个点的值取决于另外右边和下方的值

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上操作。
- 🌟ArrayList操作:
- 2D取值: list.get(index).get(index)
- 尺寸: list.size()
- 2D赋值: list.get(index).put(index, value)
198 💗 打家劫舍 💗 EASY
先分析状态,有打劫和不打劫两种,
- 1.如果打劫则把当前打劫的和刚才房子没被打劫前的钱数相加
- 2.如果没打劫,则取前一个房子打劫和没打劫的最大值
213 💗 打家劫舍II 💗 MID
跟version 1几乎一样,但是首尾相连,需要单独考虑,我们把抢第一家和不抢第一家分成两种情况dp,最后求最大值。
139 💗 单词拆分 💗 MID
如果i到j是valid words而且i之前是true,则0到j都是true