leetcode63. 不同路径 II(动态规划-java)

这篇具有很好参考价值的文章主要介绍了leetcode63. 不同路径 II(动态规划-java)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

leetcode63. 不同路径 II

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/unique-paths-ii

题目描述

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。

示例1:
leetcode63. 不同路径 II(动态规划-java)
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右

示例2:
leetcode63. 不同路径 II(动态规划-java)
输入:obstacleGrid = [[0,1],[0,0]]
输出:1

提示:
m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j] 为 0 或 1

暴力递归

这题是leetcode62. 不同路径 的拓展版.加了障碍物,解题思路是一样的,只是要加下障碍物的判断.
还是向下和向右两个方向的选择,两种情况的和就是所有的路线数.

代码演示

/**
* 主方法
*/
 public int uniquePathsWithObstacles(int[][] obstacleGrid) {
 	//如果右下角是障碍物,怎么都过不去,直接返回0
        if(obstacleGrid[obstacleGrid.length - 1][obstacleGrid[0].length - 1] == 1){
            return 0;
        }
        //开始递归
        return process(obstacleGrid,0,0);
    }
	/**
	* 暴力递归
	* i 和 j 描述当前在的位置
	*/
    public int process(int[][]obstacleGrid,int i,int j){
    	//base case 来到最后一个位置,前面路线有效,返回1
        if(i == obstacleGrid.length - 1 && j == obstacleGrid[0].length - 1 ){
            return 1;
        }
        //越界,路线无效 返回0
        if(i >= obstacleGrid.length || j >= obstacleGrid[0].length){
            return 0;
        }
        // 碰到障碍物,无效返回0
        if(obstacleGrid[i][j] == 1){
            return 0;
        }
        //x向下和向右两种情况
        int down = process(obstacleGrid,i + 1,j);
        int right = process(obstacleGrid,i,j + 1);
        //两种情况累加就是所有的路线
        return down + right;
    }

动态规划

从暴力递归中可以得知,(i,j) 位置依赖 (i+1,j)和(i,j+1)两个位置,所以可以轻松得到状态转移方程是:

f(i,j) = f(i+1,j) + f(i,j+1;
但这里有一些需要注意的地方,就是障碍物的处理,和dp表的初始化,我们以图为例:
leetcode63. 不同路径 II(动态规划-java)
上面图代表要走的网格,我只填写了最后一行和一列其他位置没有标注,因为现在只讨论最后一行和一列的情况.
最后一行为例,三角符号标注的位置是最后一次出现的障碍物,在这个障碍物之前的最后一行位置,都无法到最后位置了,所以之前的位置在dp 表中要初始化为0,之后的可以初始化为1,
最后一列也是同样情况:
下面看下代码中如何处理;

代码演示

  /**
     * 动态规划
     * @param obstacleGrid
     * @return
     */
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int n = obstacleGrid.length;
        int m = obstacleGrid[0].length;
        //最有下角如果是障碍物,就无法过去,返回 0
        if (obstacleGrid[n - 1][m - 1] == 1) {
            return 0;
        }
        //动态规划表
        int[][]dp = new int[n][m];
        //来标记最后一行最后一次出现障碍物的位置
        int flagN = -1;
        //来标记最后一列最后一次出现障碍物的位置
        int flagM = -1;
        for (int i = m - 1; i >= 0;i--){
            if(obstacleGrid[n - 1][i] == 1){
                flagN = i;
                break;
            }
        }
        //最后一个障碍物之后的位置初始化为1
        for (int i = flagN + 1; i < m;i++){
            dp[n - 1][i] = 1;
        }
        //标记最后一列最后一次出现障碍物的位置.
        for (int j =  n - 1; j >= 0;j--){
            if(obstacleGrid[j][m - 1] == 1){
                flagM = j;
                break;
            }
        }
        //最后一个障碍物之后的位置初始化为1
        for (int j = flagM + 1; j < n;j++){
            dp[j][m - 1] = 1;
        }

        for (int i = n - 2;i >= 0;i--){
            for (int j = m - 2;j >= 0;j--){
                //当前位置本身是障碍物 即为0
                if(obstacleGrid[i][j] == 1){
                    dp[i][j] = 0;
                }else{
                    //z状态转移方程
                    dp[i][j] = dp[i + 1][j] + dp[i][j + 1];
                }

            }
        }
        return dp[0][0];
    }

动态规划空间压缩

  /**
     * 动态规划 + 空间压缩
     * @param obstacleGrid
     * @return
     */
    public int uniquePathsWithObstacles2(int[][] obstacleGrid) {
        int n = obstacleGrid.length;
        int m = obstacleGrid[0].length;
        if (obstacleGrid[n - 1][m - 1] == 1) {
            return 0;
        }
        int[]dp = new int[m];
        int flagN = -1;
        for (int i = m - 1; i >= 0;i--){
            if(obstacleGrid[n - 1][i] == 1){
                flagN = i;
                break;
            }
        }
        for (int i = flagN + 1; i < m;i++){
            dp[i] = 1;
        }
        int flagM = -1;
        for (int j =  n - 1; j >= 0;j--){
            if(obstacleGrid[j][m - 1] == 1){
                flagM = j;
                break;
            }
        }

        for (int i = n - 2;i >= 0;i--){
            dp[m - 1] = i > flagM ? 1 : 0;
            for (int j = m - 2;j >= 0;j--){
                if(obstacleGrid[i][j] == 1){
                    dp[j] = 0;
                }else{
                    dp[j] = dp[j] + dp[j + 1];
                }

            }
        }
        return dp[0];
    }

动态规划专题

leetcode62. 不同路径

leetcode877. 石子游戏

leetcode64. 最小路径和

leetcode416. 分割等和子集

leetcode354. 俄罗斯套娃信封问题

leetcode300. 最长递增子序列

leetcode337. 打家劫舍 III文章来源地址https://www.toymoban.com/news/detail-503367.html

到了这里,关于leetcode63. 不同路径 II(动态规划-java)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 随想录Day39--动态规划: 62.不同路径 , 63. 不同路径 II

    今天的路劲问题,思想和昨天的爬楼梯一样,主要还是找到你这个位置是怎么来的,到达dp[i][j]的方法由到达dp[i - 1][j]的方法再加上到达dp[i][j - 1]的方法和。在初始化时,当i=0或者j=0时,到达他们的只有一条路劲,就是直走,所以对它进行初始化。 63. 不同路径 II 加了一个障

    2024年02月03日
    浏览(46)
  • 我在代码随想录|写代码Day33 | 动态规划| 路径问题| 62.不同路径,63. 不同路径 II,343. 整数拆分

    🔥博客介绍`: 27dCnc 🎥系列专栏: 数据结构与算法 算法入门 C++项目 🎥 当前专栏: 算法入门 专题 : 数据结构帮助小白快速入门算法 👍👍👍👍👍👍👍👍👍👍👍👍 ☆*: .。. o(≧▽≦)o .。.:*☆ ❤️感谢大家点赞👍收藏⭐评论✍️ 今日学习打卡 代码随想录 - 动态规划

    2024年03月11日
    浏览(40)
  • 【算法|动态规划No.6】leetcode63. 不同路径Ⅱ

    个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望对大家有所帮助 🍓希望我们一起努力、成长,共同进步。

    2024年02月16日
    浏览(41)
  • LeetCode刷题笔记【30】:动态规划专题-2(不同路径、不同路径 II)

    参考前文 参考文章: LeetCode刷题笔记【29】:动态规划专题-1(斐波那契数、爬楼梯、使用最小花费爬楼梯) LeetCode链接:https://leetcode.cn/problems/unique-paths/description/ 动态规划 : 创建m×n的数组, 对应这个地图, 数组 val 表示 有几种方法可以走到这一格 最开始, 第一行和第一列v

    2024年02月09日
    浏览(42)
  • 算法leetcode|63. 不同路径 II(rust重拳出击)

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? 网格中的障碍

    2024年02月16日
    浏览(37)
  • 【算法与数据结构】63、LeetCode不同路径 II

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :参考【算法与数据结构】62、LeetCode不同路径的题目,可以发现本题仅仅是多了障碍物。我们还是用动态规划来做。有障碍物的地方无法到达,因此路径数量为0,只需要将障碍物位

    2024年02月02日
    浏览(44)
  • 代码随想录Day33 LeetCode T62不同路径 LeetCode T63 不同路径II

    动规五部曲 1.确定dp数组含义 2.确定递推公式 3.初始化数组 4.确定遍历方式 5.打印dp数组查看分析问题 题目链接:62. 不同路径 - 力扣(LeetCode) 注:n行m列而不是m行n列 1.确定dp数组含义 代表到达此下标有多少条路径 2.确定递推公式 因为只能向右或者向下走,所以到达i,j这个点的

    2024年02月06日
    浏览(37)
  • 动态规划——不同路径II

    63. 不同路径 II - 力扣(LeetCode)​编辑https://leetcode.cn/problems/unique-paths-ii/description/ https://leetcode.cn/problems/unique-paths-ii/description/ 问题描述:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达

    2024年01月16日
    浏览(37)
  • 【学会动态规划】不同路径 II(6)

    目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 学习一个算法没有捷径,更何况是学习动态规划, 跟我一起刷动态规划算法题,一起学会动态规划! 题目链接:63. 不同路径 II - 力扣(Leet

    2024年02月15日
    浏览(36)
  • DAY39 62.不同路径 + 63. 不同路径 II

    题目要求:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 根据“机器人每次只能向下或者向右移动一步”

    2024年02月07日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包