63. Unique Path 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.
思路:dp[i][j]记录位置(i, j)的最大位移路径数目,初始转态dp[0][0]为(0, 0)位置是否有障碍状态转移方程为:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
/*
* Time: O(n * m)
* Space: O(n * m)
*/
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& mp) {
int n = mp.size(), m = mp[0].size();
vector< vector<int> > dp(n, vector<int>(m, 0));
dp[0][0] = mp[0][0] == 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mp[i][j] == 1) continue;
if (i > 0) dp[i][j] += dp[i - 1][j];
if (j > 0) dp[i][j] += dp[i][j - 1];
}
}
return dp[n - 1][m - 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.
思路:grid[i][j]记录的是在(i, j)位置上最大的路径和状态转移方程为:grid[i][j] = grid[i][j] + min(grid[i - 1][j], grid[i][j - 1]);
/*
* Time: O(m * n)
* Space: O(1)
*/
class Solution {
private:
int nrow, ncol;
public:
int minPathSum(vector<vector<int>>& grid) {
nrow = grid.size();
if (nrow == 0) return 0;
ncol = grid[0].size();
if (ncol == 0) return 0;
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncol; j++) {
int val = grid[i][j];
int aa = 0x3f3f3f3f;
int bb = 0x3f3f3f3f;
if (i >= 1) aa = val + grid[i - 1][j];
if (j >= 1) bb = val + grid[i][j - 1];
grid[i][j] = min(aa, bb) == 0x3f3f3f3f? val: min(aa, bb);
}
}
return grid[nrow - 1][ncol - 1];
}
};
70. Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
思路:用dp[i]记录到达i阶梯的方法数目,那么dp[i] = dp[i - 1] + dp[i - 2],由于状态跳转的数目有效,用cnt代替dp[i - 1],pre代替dp[i - 2],即可优化空间复杂度
NOTE:最终的答案实际是一个斐波拉契数列
/*
* Time: O(n)
* Space: O(n)
* 用dp[i]记录到达i阶梯的方法数目,那么dp[i] = dp[i - 1] + dp[i - 2]
*/
class Solution {
public:
int climbStairs(int n) {
vector<int> dp(n + 1, 0);
dp[0] = 1;
for (int i = 1; i <= n; i++) {
dp[i] += dp[i - 1];
if (i >= 2) dp[i] += dp[i - 2];
}
return dp[n];
}
};
/*
* Time: O(n)
* Space: O(1)
* 用dp[i]记录到达i阶梯的方法数目,那么dp[i] = dp[i - 1] + dp[i - 2]
* 由于状态跳转的数目有效,用cnt代替dp[i - 1],pre代替dp[i - 2],即可优化空间复杂度
* NOTE:最终的答案实际是一个斐波拉契数列
*/
class Solution {
public:
int climbStairs(int n) {
vector<int> dp(n + 1, 0);
int cnt = 1, pre = 0;
for (int i = 1; i <= n; i++) {
int current = cnt + pre;
pre = cnt;
cnt= current;
}
return cnt;
}
};