LeetCode—unique-paths_iiunique-paths_minimum-path-sum_climbing-stairs_edit-distance(动态规划)——java

138 篇文章 0 订阅
132 篇文章 0 订阅

unique-paths

题目描述

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?

Above is a 3 x 7 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

思路解析

  • 方向是只能向右和向下走,递归式子:dp[i][j]=dp[i-1][j] + dp[i][j-1]
  • 如果只有一行的话,那每个格子只能有一种走法
  • 如果只有一列的话,那每个格子也只有一种走法
  • 行和列为0,返回0

代码

public class Solution {
    public int uniquePaths(int m, int n) {
        if(n==0||m==0)
            return 0;
        if(m==1||n==1)
            return 1;
        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];
    }
}

unique-paths-ii

题目描述

Follow up for "Unique Paths":

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as1and0respectively in the grid.

For example,

There is one obstacle in the middle of a 3x3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

The total number of unique paths is2.

Note: m and n will be at most 100.

思路解析

  • 主要区别是障碍物的问题
  • 首先判断(0,0)位置是不是障碍物,还有最后的(m-1,n-1),如果是,那就一种路径也没有
  • 否则设置为(0,0)的dp为1;
  • 然后看只有一行和只有一列的,每个格子的dp(i,j)取决于当前是否有障碍物,如果有直接设置为0;如果没有,那路径次数就是前一个路径的次数
  • 然后递推式dp[i][j] = dp[i-1][j] + dp[i][j-1];

代码

public class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m=obstacleGrid.length;
        int n=obstacleGrid[0].length;
        if(m==0||n==0)
            return 0;
        if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1)
            return 0;
        int[][] dp = new int[m][n];
        dp[0][0]=1;
        for(int i=1;i<m;i++){
            if(obstacleGrid[i][0]==1)
                dp[i][0]=0;
            else
                dp[i][0]=dp[i-1][0];
        }
        for(int i=1;i<n;i++){
            if(obstacleGrid[0][i]==1)
                dp[0][i]=0;
            else
                dp[0][i]=dp[0][i-1];
        }
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                if(obstacleGrid[i][j]==1)
                    dp[i][j]=0;
                else
                    dp[i][j]=dp[i-1][j]+dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
}

Minimum Path Sum

题目描述

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

思路解析

  • 跟上面是一样的思路,每次dp记录的路径和
  • (0,0)的dp直接是grid,后边的需要选择比较小的路径,所以需要比较

代码

public class Solution {
    public int minPathSum(int[][] grid) {
        int m=grid.length;
        int n=grid[0].length;
        if(m==0||n==0){
            return 0;
        }
        int[][] dp = new int[m][n];
        dp[0][0]=grid[0][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++){
            dp[i][0]=dp[i-1][0]+grid[i][0];
        }
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                if(dp[i-1][j]<dp[i][j-1])
                    dp[i][j]=dp[i-1][j]+grid[i][j];
                else
                    dp[i][j]=dp[i][j-1]+grid[i][j];
            }
        }
        return dp[m-1][n-1];
    }
}

Climbing-stairs

题目描述

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

思路解析

  • 动态规划:dp[n]=dp[n-1]+dp[n-2]

代码

public class Solution {
    public int climbStairs(int n) {
        if(n==0||n==1||n==2)
            return n;
        int[] dp = new int[n+1];
        dp[0]=0;
        dp[1]=1;
        dp[2]=2;
        for(int i=3;i<n+1;i++){
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
}

Edit-distance

题目描述

Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:

a) Insert a character
b) Delete a character
c) Replace a character

思路解析

  • 题意:找到能够让两个字符串相等的最少操作数
  • 动态规划方法,我们维护的变量dp[i][j]是word1的前i个字符和word2的前j个字符编辑的最少操作数
  • word[i-1]==word[j-1]时,dp[i][j] = dp[i-1][j-1],不用任何操作
  • 当word[i-1]!=word[j-1]时,有三种情况:
  • 1.插入word1的一个字符dp[i][j]=dp[i-1][j]+1;
  • 2.插入word2的一个字符dp[i][j]=dp[i][j-1]+1;
  • 3.替换,word[i-1]和word[j-1]不相等,但是前面相等,所以就是dp[i][j]=dp[i-1][j-1]+1
  • 为什么没有删除?其实删除和插入是一样的,通过删除后可以得到的,插入后也是可以得到的

代码

public class Solution {
    public int minDistance(String word1, String word2) {
        int len1 = word1.length();
        int len2 = word2.length();
        int[][] dp =new  int[len1+1][len2+1];
        for(int i=0;i<=len1;i++){
            dp[i][0]=i;//i步
        }
        for(int j=0;j<=len2;j++){
            dp[0][j]=j;//j步
        }
        for(int i=1;i<=len1;i++){
            char x = word1.charAt(i-1);//从前向后一个一个查
            for(int j=1;j<=len2;j++){
                char y = word2.charAt(j-1);
                if(x==y){
                    dp[i][j]=dp[i-1][j-1];
                }else{
                    int replace = dp[i-1][j-1]+1;
                    int insert1 = dp[i-1][j]+1;
                    int insert2 = dp[i][j-1]+1;
                    int min = Math.min(replace,insert1);
                    min = Math.min(min,insert2);
                    dp[i][j]=min;
                }
            }
        }
        return dp[len1][len2];
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值