题目一要求:
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?
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
用中文解释就是从start到finish总共有多少条路径,在只可以往下走或者往右走的情况下。
算法思路:
1)首先想到的是递归调用。递归求出往下走和往右走的和就是所求路径条数。
class Solution{
public:
int uniquePathsBackTrack(int m, int n) { if(m==1 || n==1) return 1; return uniquePaths(m-1, n) + uniquePaths(m, n-1); }
};
但是会出现超时的情况。因为子问题会被计算很多次(参考斐波拉契数列的递归求解)
2)动态规划算法一:先用一个二维数组将所有结果保存起来,这样避免重复计算;
class Solution{ public: int uniquePaths(int m, int n) { if(m <= 0 || n <= 0) return 0; vector<vector<int>> result(m,vector<int>(n,1)); for(int i = 1;i < m;++i) for(int j = 1;j < n;++j) { result[i][j] = result[i][j-1] + result[i-1][j]; } return result[m-1][n-1]; } };
3)动态规划法二:用一个一维数组来存储计算结果。
class Solution { public: int uniquePaths(int m, int n) { vector <int> result(n,1); if(m == 0 || n == 0) { return 0; } for(int i = 1;i < m;++i) for(int j = 1;j < n;++j) { result[j] = result[j] + result[j-1]; } return result[n-1]; } };
4)数学里面的组合方法:总共要走m+n-2步,其中有m-1步是往下走的,有n-1步是往右走的。本质上就是一个组合问题,也就是从m+n-2个不同元素中每次取出m-1个元素的组合数。Cm+n-2^n-1.
具体代码实现参考:http://blog.csdn.net/linhuanmars/article/details/22126357
public int uniquePaths(int m, int n) { double dom = 1; double dedom = 1; int small = m<n? m-1:n-1; int big = m<n? n-1:m-1; for(int i=1;i<=small;i++) { dedom *= i; dom *= small+big+1-i; } return (int)(dom/dedom); }
小结:
个人觉得动态规划的算法是最优的,当然要是数学计算题的话那么最后一种解法当然是最优解啦!笔试的时候比较试用。没记错的话今年阿里的秋招的时候有这么一道题。
题目二要求:
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
.
恩,意思就是1代表过不去!那么对应的结果数组这个地方就为0!!!
由于题目一中的值初始时都为1,但是对于题目二来说,初始值要看给的矩阵是否有障碍来判断!
源代码:
class Solution { public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int row = obstacleGrid.size(); int col = obstacleGrid[0].size(); int result[row][col]; result[0][0] = 1; if(obstacleGrid[0][0] == 1 || obstacleGrid[row-1][col-1] == 1) return 0; for(int i = 1;i < row; ++i) { result[i][0] = obstacleGrid[i][0] == 1 ? 0 : result[i-1][0]; } for(int j = 1;j < col;++j) { result[0][j] = obstacleGrid[0][j] == 1 ? 0 : result[0][j-1]; } for(int i = 1; i < row;++i) for(int j = 1;j < col;++j) { result[i][j] = obstacleGrid[i][j] == 1 ? 0 : result[i-1][j] + result[i][j-1]; } return result[row-1][col-1]; } };Notice:题目二和题目一的初始化是不一样的!