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.
算法思想其实都相同,打表,但打表的技巧决定算法的效率。
下面是将行列坐标映射到一个整数,即(x,y)-->100*x+y。 然后用map缓存。
class Solution {
public:
map<pair<int,int>,int> tab;
int dp(vector<vector<int>>& obstacleGrid,int x1,int y1,int x2,int y2){
if(x2<x1 || y2<y1 || obstacleGrid[x2][y2]==1) return 0;
if((x1==x2 && y2==y1+1) || (x2==x1+1 && y1==y2) || (x1==x2 && y1==y2)) return 1;
if(tab.find(make_pair(x1*100+y1,x2*100+y2))!=tab.end()) return tab[make_pair(x1*100+y1,x2*100+y2)];
int res = dp(obstacleGrid,x1,y1,x2,y2-1) + dp(obstacleGrid,x1,y1,x2-1,y2);
tab[make_pair(x1*100+y1,x2*100+y2)] = res;
return res;
}
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if(obstacleGrid[0][0]==1 || obstacleGrid.back().back()==1) return 0;
return dp(obstacleGrid,0,0,obstacleGrid.size()-1,obstacleGrid[0].size()-1);
}
};
更好的做法是将4两个坐标值压缩成一个int型数,因为坐标行列都小于等于100,所以可以用一个字节表示m,n,这样四个字节就能表示(x1,y1,x2,y2)
压缩后空间效率大大提高
class Solution {
public:
unordered_map<int,int> tab;
int encode(char x1, char y1,char x2,char y2){
return (x1<<24) + (y1<<16) + (x2<<8) + y2;
}
int dp(vector<vector<int>>& obstacleGrid,int x1,int y1,int x2,int y2){
if(x2<x1 || y2<y1 || obstacleGrid[x2][y2]==1) return 0;
if((x1==x2 && y2==y1+1) || (x2==x1+1 && y1==y2) || (x1==x2 && y1==y2)) return 1;
int code = encode(x1,y1,x2,y2);
if(tab.find(code)!=tab.end()) return tab[code];
int res = dp(obstacleGrid,x1,y1,x2,y2-1) + dp(obstacleGrid,x1,y1,x2-1,y2);
tab[code] = res;
return res;
}
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if(obstacleGrid[0][0]==1 || obstacleGrid.back().back()==1) return 0;
return dp(obstacleGrid,0,0,obstacleGrid.size()-1,obstacleGrid[0].size()-1);
}
};