二维的dp[ ] [ ]
62-不同路径
**思路:**记录每一位置的路线数,初始值最上最左设为1,dp[ i ] [ j ]=dp[ i-1 ][ j ]+dp[ i ][ j-1 ]
**注意:**注意边界从1开始遍历
java
class Solution {
public int uniquePaths(int m, int n) {
int [][]dp =new int[m][n];
for(int i=0;i<m;i++){
dp[i][0]=1;
}
for(int i=0;i<n;i++){
dp[0][i]=1;
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
64-最小路径和
**思路:**设置第一个位置初始值,由此设置上和右边界的初始值(累加)。开始遍历x位置 先判断上和左位置谁最小,然后加上当前位置,即所求值。返回最后一个。
注意: 边界已初始化,则遍历时从1开始
java
class Solution {
public int minPathSum(int[][] grid) {
int m=grid.length;
int n=grid[0].length;
int [][] dp=new int[m][n];
dp[0][0]=grid[0][0];
for(int i=1;i<m;i++){
dp[i][0]=dp[i-1][0]+grid[i][0];
}
for(int i=1;i<n;i++){
dp[0][i]=dp[0][i-1]+grid[0][i];
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
return dp[m-1][n-1];
}
}
5-最长回文子串
**思路:**用dp[ i ][ j ]来表示长度为i到j的是否回文,先判断特殊情况s为空,再判断长度为1,为2时;再执行长度为3,用start取匹配时的位置,用maxlen更新匹配时的最大长度。
核心判断:s.charAt( i )==s.charAt( j )&&dp[ i+1 ][ j-1]
**注意:**判断完边界再判断内部是否回文;
获取元素用charAt( ) , 截取用substring( i, j )
循环用长度len来走外循环
java
class Solution {
public String longestPalindrome(String s) {
int n=s.length();
if(n<2) {return s;}//s长度为0,1时
boolean [][]dp =new boolean[n][n];//代表判断长度i,j之间的内容
int maxlen=1; //用于结果返回,最大长度
int start =0;//用于结果返回,开始值
for(int i=0;i<n;i++){//初始化长度为1的
dp[i][i]=true;
}
for(int i=0;i<n-1;i++){//初始化长度为2的
if(s.charAt(i)==s.charAt(i+1)){
dp[i][i+1]=true; //初始化i和i+1区间的值(长度为2)
if(maxlen<2){ //更新取值
maxlen=2;
start=i; //获取当前i(从0开始遍历的)
}
}
}
//从头开始,走s长度为3及以上的情况
for(int len=3;len<=n;len++){
for(int i=0;i+len<=n;i++){
int j=i+len-1; //右边界的值
//判断边界是否回文,以及内部是否回文,小的值已初始
if(s.charAt(i)==s.charAt(j)&&dp[i+1][j-1]){
dp[i][j]=true;
if(maxlen<len){
maxlen=len; //更新最长值
start=i; //获取当前i(从0开始遍历的)
}
}
}
}
return s.substring(start,start+maxlen);//截取用substring()函数
}
}
1143-最长公共子序列
思路:dp[ i ][ j ] 表示text1[ i ] 和text2[ j ] 的最长相同序列数,判断两串对应位置是否相同,并加一,否则选dp[ i-1][ j ] 或者**dp[ i ][ j -1]**的最大值
注意: 求数字则初始值为索引,从0开始,长度为n+1;
遍历时从1索引开始,可等于m、n , 判断方式看[ n-1 ]是否越界
java
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int m=text1.length();
int n=text2.length();
int [][]dp=new int[m+1][n+1];//存两个位置i和j相同字符的最大数量
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(text1.charAt(i-1)==text2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j]);
}
}
}
return dp[m][n];
}
}
72-编辑距离
思路:
情况 1:
dp[0][j] = j:空字符串变成 word2[0..j-1],需要插入 j 个字符
dp[i][0] = i:word1[0..i-1] 变成空字符串,需要删除 i 个字符
情况 2:word1[i-1] == word2[j-1] 不用做任何操作,直接继承之前的结果:
dp[i][j] = dp[i-1][j-1]
情况 3:word1[i-1] != word2[j-1] 三种操作取最小值:
java
dp[i][j] = min(
dp[i-1][j] + 1, // 删除 word1[i-1]
dp[i][j-1] + 1, // 插入 word2[j-1]
dp[i-1][j-1] + 1 // 替换
)
**注意:**求数字则初始设置m+1长度,;
若相等则+1, 不等则考虑(删除、插入、替换)三者最小值,再+1;
注意条件边界取值
java
class Solution {
public int minDistance(String word1, String word2) {
int m=word1.length();
int n=word2.length();
int [][]dp=new int[m+1][n+1];
for(int i=0;i<=m;i++){//若一串为0时
dp[i][0]=i;
}
for(int j=0;j<=n;j++){
dp[0][j]=j;
}
//若相等
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(word1.charAt(i-1)==word2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1];//与前一个相比,不需要改,数量相等直接继承
}
else{
//不等时,选三个的最小值 并+1
dp[i][j]=Math.min(Math.min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;
}
}
}
return dp[m][n];
}
}







