[LeetCode]Unique Paths (动态规划)

62. Unique Paths

问题

A robot is located at the top-left corner of a m × 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 × 7 grid. How many possible unique paths are there?

Note: m and n will be at most 100.


思路

  • 让左上角的起点格子坐标为(0,0)。
  • 当只有一个格子时,只有一种走法。
  • 当只有一行或只有一列格子时,走法也是1。
  • 当有多行多列格子时,由于只能往右或往下走,所以对于一个给定的格子,来到这个格子的方法只能是从左边过来或从上边下来。所以来到这个格子的方法数等于左边格子的方法数加上上边格子的方法数。即uniquePaths(m, n) = uniquePaths(m - 1, n) + uniquePaths(m, n - 1)

步数矩阵示例

        +----+----+----+----+----+----+----+----+
        | 1  | 1  | 1  | 1  | 1  | 1  | 1  | 1  |
        +----+----+----+----+----+----+----+----+
        | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  |
        +----+----+----+----+----+----+----+----+
        | 1  | 3  | 6  | 10 | 15 | 21 | 28 | 36 |
        +----+----+----+----+----+----+----+----+
        | 1  | 4  | 10 | 20 | 35 | 56 | 84 |120 |
        +----+----+----+----+----+----+----+----+
  • 起始状态:最左边一列和最上边一行的步数都是1

代码

public class UniquePaths {
    public int uniquePaths(int m, int n) {
        if (m == 0 || n == 0)
            return 1;
        int[][] paths = new int[m][n]; // 存储每个格子的步数
        for (int i = 0; i < m; i++) {
            paths[i][0] = 1; // 最左边一列设置为1
        }
        for (int i = 0; i < n; i++) {
            paths[0][i] = 1; // 最上边一行设置为1
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                paths[i][j] = paths[i - 1][j] + paths[i][j - 1]; // 左边步数加上上边步数
            }
        }
        return paths[m - 1][n - 1]; // 返回最后一个元素
    }
}

63. 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 as 1 and 0 respectively 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 is 2.

Note: m and n will be at most 100.


思路

  • 基本与上一题一样。
  • 不同之处在于:
    1. 初始化dp数组的行和列时,遇到障碍物了,之后全部都设置为0。
    2. 递归过程中,遇到障碍物,将此位置设置为0即可

代码

public class UniquePaths_II {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int line = obstacleGrid.length; // 行数
        int row = obstacleGrid[0].length; // 列数
        int[][] paths = new int[line][row];
        for (int i = 0; i < row; i++) { // 第一行 注意,一旦遇到有障碍,这一行后面所有全部设置为0

            if (obstacleGrid[0][i] == 1) {
                while (i < row) {
                    paths[0][i] = 0;
                    i++;
                }
            } else
                paths[0][i] = 1;
        }

        for (int i = 0; i < line; i++) { // 第一列 一旦遇到障碍,这一列剩余所有全部设置为0
            if (obstacleGrid[i][0] == 1) {
                while (i < line) {
                    paths[i][0] = 0;
                    i++;
                }
            } else
                paths[i][0] = 1;
        }

        for (int i = 1; i < line; i++) {
            for (int j = 1; j < row; j++) {
                if (obstacleGrid[i][j] != 1) {
                    paths[i][j] = paths[i - 1][j] + paths[i][j - 1];
                } else {
                    paths[i][j] = 0;
                }
            }
        }
        return paths[line - 1][row - 1];
    }
}

64. 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.


思路

基本思路与第一题一样。给定的格子带有自己的步数,要求最短步数,就把给定格子自己的步数加上左边和上边格子中步数较小的一个。
初始化:
1. 左上角设置为给定网格的第一个格子里的数。
2. 第一行和第一列,设置为此格子自己的步数加上前一个格子的步数。


代码

public class MinimumPathSum {
    public int minPathSum(int[][] grid){
        int row = grid[0].length;
        int line = grid.length;
        int[][] dp = new int[line][row];
        dp[0][0]=grid[0][0]; // 左上角设置为给定网格的第一个格子里的数

        for(int i=1;i<line;i++){ // 初始化第一行
            dp[i][0]=grid[i][0]+dp[i-1][0];
        }
        for(int i=1;i<row;i++){ // 初始化第一列
            dp[0][i]=grid[0][i]+dp[0][i-1];
        }

        for(int i=1;i<line;i++){ // 递归
            for(int j=1;j<row;j++){
                // 定格子自己的步数加上左边和上边格子中步数较小的一个
                dp[i][j]=Math.min(dp[i-1][j], dp[i][j-1])+grid[i][j];
            }
        }
        return dp[line-1][row-1];
    }
}

参考
  1. 62. / 63. Unique Paths(I / II)
  2. 第一题矩阵图
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值