Problem
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?
Note: m and n will be at most 100.
具体详见Leetcode
Unique PathsII
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.
具体详见Leetcode
Analysis
算法
Unique Paths
每一个格子有两个行进方向,它只能从右边或者下面到达下一个格子,然后不管怎么走,终点是右下角的那个格子。所以,我们可以从右下角格子反走到左上角。从右下角出发,当前的方法数初始值为1,然后从这个格子出发,每个格子的方法数是它右边和下面的格子的方法数的总和,一直到(0,0)。
设
f[i][j]
为在i行j列的格子走到右下角的格子的方法数。
f[i][j]=f[i+1][j]+f[i][j+1]
最后的答案是
f[0][0]
Complexity
时间复杂度:
O(n2)
空间复杂度:
O(n2)
Unique PathsII
与上一题不同的是,这道题还加了障碍,矩阵中元素的值为1的就是障碍,障碍是不能通过的。首先还是让右下角的格子方法数为1(在它不为1的情况下,如果它为1,则永远不可能到达终点,所以方法数为0),当前格子的路径数为:下面格子的路径数(当右边格子为障碍时);右边格子的路径数(当下面格子为障碍时);两边格子的路径数之和;-1(下面的格子和右边的格子都有障碍)。
状态转移方程和上题一致,但是还要加入条件判断。最后如果(0,0)处的方法数算出来是-1,则说明终点不可达,返回路径数为0。
Complexity
时间复杂度:
O(n2)
空间复杂度:
O(n2)
Code
Unique Paths
class Solution {
public:
int uniquePaths(int m, int n) {
int** matrix = new int*[m];
for (int i = 0; i < m; i++) {
matrix[i] = new int[n];
}
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
int r1 = i + 1;
int c1 = j + 1;
if (r1 >= m && c1 >= n) matrix[i][j] = 1;
else if (r1 >= m) matrix[i][j] = matrix[i][c1];
else if (c1 >= n) matrix[i][j] = matrix[r1][j];
else matrix[i][j] = matrix[i][c1] + matrix[r1][j];
}
}
int answer = matrix[0][0];
for (int i = 0; i < m; i++) {
delete matrix[i];
}
delete matrix;
return answer;
}
};
Unique PathsII
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
if (m == 0) return 0;
int n = obstacleGrid[0].size();
if (n == 0) return 0;
if (obstacleGrid[m-1][n-1] == 1) return 0;
int** matrix = new int*[m];
for (int i = 0; i < m; i++) {
matrix[i] = new int[n];
}
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
int r1 = i + 1;
int c1 = j + 1;
if (r1 >= m && c1 >= n) matrix[i][j] = 1;
else if (r1 >= m) matrix[i][j] = matrix[i][c1];
else if (c1 >= n) matrix[i][j] = matrix[r1][j];
else if (matrix[r1][j] == -1) matrix[i][j] = matrix[i][c1];
else if (matrix[i][c1] == -1) matrix[i][j] = matrix[r1][j];
else matrix[i][j] = matrix[i][c1] + matrix[r1][j];
if (obstacleGrid[i][j] == 1) matrix[i][j] = -1;
}
}
int answer = matrix[0][0];
if (answer == -1) answer = 0;
for (int i = 0; i < m; i++) {
delete matrix[i];
}
delete matrix;
return answer;
}
};