一.不同路径
问题概述:

只能向右走和向下走,请问从Start到Finish一共几条路。
思路:
动态规划思想,明确边界条件,第一行和第一列到的格子路径只有1条。其他格子的路径是他左边格子的路径加上上面格子的路径。依次类推。

代码:
java
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp=new int[m][n];
for(int i=0;i<n;i++){
dp[0][i]=1;
}
for(int i=0;i<m;i++){
dp[i][0]=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];
}
}
二.最小路径和
问题概述:

从左上角走到右下角,路径最短。
思路:
动态规划思想,与上题类似,第一行和第一列到各点的路径都是确定的,剩下的格子就比较其值加上左边格子值和其值加上上面格子值哪个小,不断延申。

代码:
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]=grid[i][0]+dp[i-1][0];
}
for(int i=1;i<n;i++){
dp[0][i]=grid[0][i]+dp[0][i-1];
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=Math.min(dp[i-1][j]+grid[i][j],dp[i][j-1]+grid[i][j]);
}
}
return dp[m-1][n-1];
}
}
三.最长回文子串
问题概述:

输出最长回文子串。
思路:
①动态规划

dpij表示si,j,如果为回文数则标记为T,否则为F。不同色块代表取不同的字符串长度,比如粉色代表长度为1,土色代表长度为2。所以从图中可以知道,我们只要找到越接近右上角的"T"就行了,因为越接近右上角字符串长度越长。
代码:
java
class Solution {
public String longestPalindrome(String s) {
int n=s.length();
boolean dp[][]=new boolean[n][n];
int start=0;
int maxl=1;
//总长度长度为1,显然是回文子串,直接返回。
if(n==1){
return s;
}
//总长度>1,从子串长度为1开始寻找,一直到长度为n。首先对长度为1的子串标记为"T"
for(int i=0;i<n;i++){
dp[i][i]=true;
}
//从长度为2的子串开始,继续寻找。
for(int len=2;len<=n;len++){
for(int i=0;i<=n-len;i++){
int j=i+len-1;
//长度为2,只需比较首位俩值是否相等,长度大于2比较首尾部两值以及去掉首尾是否为回文。
if(len==2){
dp[i][j]=s.charAt(i)==s.charAt(j);
}else{
dp[i][j]=s.charAt(i)==s.charAt(j)&&dp[i+1][j-1];
}
//如果为回文,且长度大于maxl,则更新
if(dp[i][j]==true && len>maxl){
start=i;
maxl=len;
}
}
}
return s.substring(start,start+maxl);
}
}
四.最长公共子序列
问题概述:

找出离散,但是出现顺序一致的子串的最大值。
思路:


代码:
java
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int m=text1.length()+1;
int n=text2.length()+1;
int[][] dp=new int[m][n];
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-1][n-1];
}
}
五.编辑距离
问题概述:


思路:


左边为world1,上边为world2。第一行world1为"",要想变为上边的world2只要插入相应的数量的字符就行。
第一列world2为"",world1要想变world2只要删除相应数量的字符就行。
hors->cose需要几步操作,可以拆分为hor->cos (替换),hor->cose(插入),hors->cos(插入),取这三个操作最小值。
如果最后一个字符相等,比如ho->co就不需要操作,等效于h->c。
代码:
java
class Solution {
public int minDistance(String word1, String word2) {
int m=word1.length()+1;
int n=word2.length()+1;
int[][] dp=new int[m][n];
for(int i=0;i<m;i++){
dp[i][0]=i;
}
for(int i=0;i<n;i++){
dp[0][i]=i;
}
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{
dp[i][j]=Math.min(dp[i-1][j-1]+1,Math.min(dp[i-1][j]+1,dp[i][j-1]+1));
}
}
}
return dp[m-1][n-1];
}
}