62.不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7 输出:28示例 2:
输入:m = 3, n = 2 输出:3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 1. 向右 -> 向下 -> 向下 2. 向下 -> 向下 -> 向右 3. 向下 -> 向右 -> 向下示例 3:
输入:m = 7, n = 3 输出:28
本题会想到是一个深度搜索的问题,用二叉树求解,但是这样会超出时间限制,这种下一步需要上一步来推导的,可以优先考虑动态规划。因为本题要求有多少条从起点到终点的可能路径,这里需要定义的是一个二维数组,因为坐标包括两个值,start为[0,0],end为[m-1, n-1]。dp为路径条数。。题目规定每次只能向右或向下移动。所以到终点end的时候,上一步只能是来自其左边或者上边,所以end的位置只能来自(m-2, n-1)或(m-1, n-2)。
- 确定dp数组以及下标的含义:dp[i][j]表示从(0,0)出发,到(i, j) 有dp[i][j]条不同的路径。
- 确定递推公式:因为终点只能通过其左或者上面到达,所以dp[i][j]=dp[i-1][j]+dp[i][j-1]
- dp数组如何初始化:因为只能从上或左走,不存在斜着走的情况,所以从(0,0)到达(0,n)或(m,0)只能一直向下或向左,可能路径条数均为1,即dp[i][0]=1,dp[0][j]=1
- 确定遍历顺序:遍历顺序就是从1开始左向右,从上到下一层层遍历
- 举例推导dp数组:这里没法直接给出dp的举例
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp=new int[m][n];
for(int i=0;i<m;i++) dp[i][0]=1;
for(int j=0;j<n;j++) dp[0][j]=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];
}
}
63. 不同路径 II
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
本意跟上一题不用路径的区别在于,这里多了障碍物的限制条件,因此当存在障碍物的时候,这条路径就被去掉即可,因此初始化和遍历时,都需要多加一个判断障碍物的条件,如果(i,j)位置有障碍物,就为0。如果起点和终点有障碍物,则为0。
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
//先定义m和n
int m=obstacleGrid.length;
int n=obstacleGrid[0].length;
int[][] dp= new int[m][n];
if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1) return 0;
for(int i=0;i<m && obstacleGrid[i][0]==0;i++) dp[i][0]=1;
for(int j=0;j<n && obstacleGrid[0][j]==0;j++) dp[0][j]=1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(obstacleGrid[i][j]==1) continue;
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}