LeetCode-063-不同路径 II
不同路径 II
题目描述:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
示例说明请见LeetCode官网。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths-ii/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一:递归法
首先,经过分析可知,到达任意一个单元格子的最后一步,可以从这个格子的左边过来,也可以从这个格子的上边过来,所以到达任意一个格子的步数是到它左边的步数加上到它上面格子的步数之和,所以可以用递归的方法求解,具体过程如下:
- 如果m等于1或者n等于1,直接返回1;
- 如果上面的条件不满足,则递归调用该方法求解
uniquePaths(m - 1, n) + uniquePaths(m, n - 1)。说明:和LeetCode-062-不同路径的区别在于,当左边或者上面的走法为0(即走不通的时候),则只用继续往一个方向递归。
解法二:迭代法
首先记录第一行的格子的走法columns,从第一个元素开始判断,如果第一个元素的值为1(即有障碍物),则为0,然后给columns的后面的元素赋值,赋值时需要同时判断前面一个元素的值和当前位置是否有障碍物。然后根据columns迭代获取下面每一行相应的走法,迭代过程如下:
- 首先根据上一行第一个元素的值和当前行第一个元素是否有障碍物获取columns[0]的值;
- 然后重复上面的过程,给columns的后面的元素赋值,赋值时需要同时判断前面一个元素的值和当前位置是否有障碍物。
最后返回columns最后一个元素的值即为最终的走法。
说明:解决过程类似 LeetCode-062-不同路径,特别注意当第一个元素为1时,则走不通;当只有一个元素时,且为0时,返回1也就是有一种走法,而不是返回0。
public class LeetCode_063 {
/**
* 递归法
*
* @param obstacleGrid
* @return
*/
public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
if (m == 1 && n == 1) {
if (obstacleGrid[m - 1][n - 1] == 1) {
return 0;
} else {
return 1;
}
}
if (obstacleGrid[m - 1][n - 1] == 1) {
return 0;
}
return uniquePathsWithObstacles(obstacleGrid, obstacleGrid.length - 1, obstacleGrid[0].length - 1);
}
private static int uniquePathsWithObstacles(int[][] obstacleGrid, int x, int y) {
if (obstacleGrid[x][y] == 1) {
return 0;
}
if (x == 0 && y == 0) {
if (obstacleGrid[x][y] == 1) {
return 0;
} else {
return 1;
}
}
if (x > 0) {
if (y > 0) {
if (obstacleGrid[x - 1][y] == 1) {
if (obstacleGrid[x][y - 1] == 1) {
return 0;
} else {
return uniquePathsWithObstacles(obstacleGrid, x, y - 1);
}
} else {
if (obstacleGrid[x][y - 1] == 1) {
return uniquePathsWithObstacles(obstacleGrid, x - 1, y);
} else {
return uniquePathsWithObstacles(obstacleGrid, x - 1, y) + uniquePathsWithObstacles(obstacleGrid, x, y - 1);
}
}
} else {
if (obstacleGrid[x - 1][y] == 1) {
return 0;
} else {
return uniquePathsWithObstacles(obstacleGrid, x - 1, y);
}
}
} else {
if (obstacleGrid[x][y - 1] == 1) {
return 0;
} else {
return uniquePathsWithObstacles(obstacleGrid, x, y - 1);
}
}
}
/**
* 迭代法
*
* @param obstacleGrid
* @return
*/
public static int uniquePathsWithObstacles2(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int[] columns = new int[n];
if (obstacleGrid[0][0] == 1) {
columns[0] = 0;
} else {
columns[0] = 1;
}
// 初始化第一行
for (int i = 1; i < n; i++) {
if (columns[i - 1] == 0) {
columns[i] = 0;
continue;
}
if (obstacleGrid[0][i] == 1) {
columns[i] = 0;
} else {
columns[i] = 1;
}
}
// 迭代过程
for (int i = 1; i < m; i++) {
// 第一个值
if (columns[0] == 0) {
for(int x = 1; x < n; x++) {
if(obstacleGrid[i][x] == 1) {
columns[x] = 0;
} else {
columns[x] = columns[x - 1] + columns[x];
}
}
continue;
}
if (obstacleGrid[i][0] == 1) {
columns[0] = 0;
} else {
columns[0] = 1;
}
for (int j = 1; j < n; j++) {
if (obstacleGrid[i][j] == 1) {
columns[j] = 0;
} else {
columns[j] = columns[j] + columns[j - 1];
}
}
}
return columns[n - 1];
}
public static void main(String[] args) {
int[][] obstacleGrid = new int[][]{{0}, {1}};
System.out.println(uniquePathsWithObstacles(obstacleGrid));
System.out.println(uniquePathsWithObstacles2(obstacleGrid));
}
}
【每日寄语】 机会不会等你,错过以后可能不会再有。
LeetCode-063-不同路径 II的更多相关文章
- Leetcode 063 不同路径二
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为" ...
- Java实现 LeetCode 63 不同路径 II(二)
63. 不同路径 II 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在 ...
- [LeetCode] 63. 不同路径 II ☆☆☆(动态规划)
描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 现在 ...
- LeetCode 63. 不同路径 II(Unique Paths II)
题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). ...
- Java for LeetCode 063 Unique Paths II
Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...
- leetcode 63 不同路径II
二维数组动态规划,还可以采用一维数组进行动态规划. class Solution { public: int uniquePathsWithObstacles(vector<vector< ...
- Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II)
Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II) 初级题目:Leetcode之动态规划(DP)专题-62. 不同路径(Unique Paths) 一个机 ...
- LeetCode:不同路径&不同路径II
不同路径一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 问 ...
- 刷题-力扣-63. 不同路径 II
63. 不同路径 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-paths-ii/ 著作权归领扣网络所有.商业转 ...
随机推荐
- WTM多租户改造
首先简单说下多租户的几种实现方式 多租户(Multi-Tenant ),即多个租户共用一个实例,租户的数据既有隔离又有共享,说到底是要解决数据存储的问题. 常用的数据存储方式有三种. 方案一:独立数据 ...
- Java 锁 概念介绍
一 Java中的锁是什么? /* * 一 Java锁定义? * 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制. * 锁旨在强制 ...
- [HNOI2009]双递增序列
不难发现本题贪心是不好做的,可以考虑 \(dp\). 首先的一个想法就是令 \(dp_{i, j, k, l}\) 表示当前选到第 \(i\) 个位置,当前第一个序列选了 \(j\) 个数,当前第一个 ...
- JAVA多线程提高十四:同步工具Exchanger
Exchanger可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象.Exchanger 可能被视 ...
- 对JSP中的Session 简单理解
我的理解: 简单来说,要使用服务器端的session对象,就是要有其对应的key,即sessionid,它只认识sessionid. 下面我说的cookie,url重写或者隐藏表单,都是为了将其对应的 ...
- js Object.prototype.hasOwnProperty() 与 for in 区别
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性 语法 obj.hasOwnProperty(prop) 参数 prop要检测的属性 [字符串] 名称或者 ...
- 微信小程序开发提升效率
http://www.ifanr.com/minapp/790017 微信小程序的 API 实现需要兼顾方方面面,所以仍然使用 callback 写法. 众所周知,Callback-Hell(回调地狱 ...
- Redis常用数据类型以及操作
Redis常用数据类型以及操作 目录 Redis常用数据类型以及操作 一.String数据类型 1. SET/GET/APPEND/STRLEN 2. INCR/DECR/INCRBY/DECRBY ...
- Linux防火墙(iptables/firewalld)
Linux防火墙(iptables/firewalld) 目录 Linux防火墙(iptables/firewalld) 一.iptables 1. iptables概述 2. netfilter和i ...
- 二叉树的基本操作(C语言版)
今天走进数据结构之二叉树 二叉树的基本操作(C 语言版) 1 二叉树的定义 二叉树的图长这样: 二叉树是每个结点最多有两个子树的树结构,常被用于实现二叉查找树和二叉堆.二叉树是链式存储结构,用的是二叉 ...