确定dp数组(dp table)以及下标的含义
dp[i]:包括下标i之前的最大连续子序列和为dp[i]。
2.确定递推公式
dp[i]只有两个方向可以推出来:
dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和
nums[i],即:从头开始计算当前连续子序列和
一定是取最大的,所以dp[i] = max(dp[i - 1] + nums[i], nums[i]);
3.初始化
dp[0]=nums[0]
4.返回结果
在递推公式的时候直接选出最大的dp[i]
class Solution {
public int maxSubArray(int[] nums) {
int[] dp=new int[nums.length];
int res=nums[0];
dp[0]=nums[0];
for(int i=1;i<nums.length;i++){
dp[i]=Math.max((dp[i-1]+nums[i]),nums[i]);
if(dp[i]>res) res=dp[i];
}
return res;
}
}
确定dp数组(dp table)以及下标的含义
dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。
2.确定递推公式
这一类问题,基本是要分析两种情况
s[i - 1] 与 t[j - 1]相等
s[i - 1] 与 t[j - 1] 不相等
当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。
一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。
如果 s[i-1]s[i−1] 不和 t[j-1]t[j−1] 匹配,则考虑 t[j-1]t[j−1] 作为 s[i-2]s[i−2] 的子序列,子序列个数为 dp[i-1][j]dp[i−1][j]。
所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配,即:dp[i - 1][j]
所以递推公式为:dp[i][j] = dp[i - 1][j];
3.初始化
dp[i][0] 表示:以i-1为结尾的s可以随便删除元素,出现空字符串的个数。
那么dp[i][0]一定都是1,因为也就是把以i-1为结尾的s,删除所有元素,出现空字符串的个数就是1。
再来看dp[0][j],dp[0][j]:空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数。
那么dp[0][j]一定都是0,s如论如何也变成不了t。
dp[0][0]=1,空字符串s,可以删除0个元素,变成空字符串t。
class Solution {
public int numDistinct(String s, String t) {
int[][] dp=new int[s.length()+1][t.length()+1];
for(int i=0;i<s.length();i++){
dp[i][0]=1;
}
for(int j=1;j<t.length();j++){
//j从1开始因为dp[0][0]应该是1,即空字符串s,可以删除0个元素,变成空字符串t。
dp[0][j]=0;
}
for(int i=1;i<=s.length();i++){
for(int j=1;j<=t.length();j++){
if(s.charAt(i - 1) == t.charAt(j - 1)){
dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
}else{
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[s.length()][t.length()];
}
}
情况二:删word2[j - 1],最少操作次数为dp[i][j - 1] + 1
情况三:同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2
取最小值,即dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
因为dp[i - 1][j - 1] + 1等于 dp[i - 1][j] 或 dp[i][j - 1],所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
3.初始化
dp[i][0]:word2为空字符串,以i-1为结尾的字符串word1要删除多少个元素,才能和word2相同呢,很明显dp[i][0] = i
dp[0][j]=j
class Solution {
public int minDistance(String word1, String word2) {
int[][] dp=new int[word1.length()+1][word2.length()+1];
for(int i=0;i<=word1.length();i++){
dp[i][0]=i;
}
for(int j=0;j<=word2.length();j++){
dp[0][j]=j;
}
for(int i=1;i<=word1.length();i++){
for(int j=1;j<=word2.length();j++){
if(word1.charAt(i-1)==word2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1];
}else{
dp[i][j]=Math.min(dp[i-1][j]+1,dp[i][j-1]+1);
}
}
}
return dp[word1.length()][word2.length()];
}
}