62.不同路径
本题重点在于把路径问题转换为数列递归函数问题,着眼点在于观察终点可以由哪些路径达到:它的上方或左侧,那么递归函数也就得出来了:
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];
}
}
此外,dp数组的初始化也要注意,首先便是dp数组的大小,定义成:
vector<vector<int>>dp(m,vector<int>(n,0));
同时需要给dp数组赋初始值,需要观察:dp[0][2]=1,dp[2][0]=1,也就是说数组的边界值都是1这样,dp数组的初始化就完成了:
for(int i=0;i<m;i++)dp[i][0]=1;
for(int j=0;j<n;j++)dp[0][j]=1;
63. 不同路径 II
与上一题类似,定义同样大小的dp数组,并对边界值赋值,随后对没有障碍的点根据递归函数进行计算。
需要注意的点:
1、获得给定数组的大小m,n:
int m=obstacleGrid.size();
int n=obstacleGrid[0].size();//为什么1不行啊,不都一样,啊
注意此处一定要用obstacleGrid[0]而不是1,不然会报错,因为可能存在数组只有一行,以后都记住,一定要用二维数组第一个元素获得其大小。
2、其次就是dp数组的初始化,对于边界值dp[i][0],dp[0][i],只要不是障碍物都赋值为1:
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=0;i<m;i++){
if(obstacleGrid[i][0]==0){
dp[i][0]=1;
}
}
for(int j=0;j<n;j++){
if(obstacleGrid[0][j]==0){
dp[0][j]=1;
}
}
这样在当前行行到障碍物时还会继续走下去,应该避免。
3、最后则是对于可能出现障碍物时,我本来的算法是分多种情况,上面是障碍物,左侧是障碍物时应该怎么做,但是转念一想,对于有障碍物的节点,当前节点跳过就行了:
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];
}
}