leetcode 63 不同路径II
一、题目描述


二、解题思路
解法一:深度优先搜索(超时)
(1)uniquePathsWithObstacles函数
<1>边界处理,如果起点或者终点是障碍物,就返回0;
<2>否则,就对起点(0,0)位置调用dfs函数,寻找合法路径;
<3>最终返回path,即为所求;
(2)dfs函数
<1>函数功能:dfs函数用于寻找以(i,j)为起点,(m-1,n-1)位置为终点的合法路径的数量;
<2>函数实现:
1)递归出口:如果起点为终点,就将path++,并return;
2)函数体:按照右、下的顺序探索(i,j)位置的相邻块(x,y),如果合法就对(x,y)位置调用dfs函数;
解法二:动态规划
(1)dp[row][col]的含义
dp[row][col]表示从起点到(row,col)位置的合法路径的总数;
(2)初始化
需要对第一行和第一列进行初始化,如果当前行(列)当前位置之前没有障碍物,则dp[row][col]=1,否则,障碍位置之后的所有位置均不可到达,即dp[row][col]=0。
例如,当obstacleGrid=[[0,1,0,0]],则第一行障碍物位置及其后面的位置均不可达,为dp[row][col]为0;
(3)状态转移方程
由于机器人只能向右或者向下行走,所以dp[row][col]=dp[row-1][col]+dp[row][col-1](row>=1&&col>=1);
三、代码实现
解法一:深度优先搜索(超时)
class Solution {int m,n;int path;
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {//深度优先搜索m=obstacleGrid.size();n=obstacleGrid[0].size();path=0;//边界处理if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1) return 0;dfs(obstacleGrid,0,0);return path;}int dx[2]={0,1};int dy[2]={1,0};void dfs(vector<vector<int>>& obstacleGrid,int i,int j){//递归出口if(i==m-1&&j==n-1){path++;return ;}for(int k=0;k!=2;k++){int x=i+dx[k];int y=j+dy[k];if(x>=0&&x<m&&y>=0&&y<n&&obstacleGrid[x][y]==0)dfs(obstacleGrid,x,y);}}
};
解法二:动态规划
class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {//动态规划int m=obstacleGrid.size();int n=obstacleGrid[0].size();//边界处理if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1)return 0;vector<vector<int>>dp (m,vector<int>(n,0));//初始化第一行(列)int flag=0; //flag用于标志第一行(列)是否已经遇到了障碍for(int i=0;i!=m;i++) {if(obstacleGrid[i][0]==1)flag=1;dp[i][0]=flag==1?0:1;}flag=0;for(int j=0;j!=n;j++){if(obstacleGrid[0][j]==1)flag=1;dp[0][j]=flag==1?0:1;}//填写dp数组剩余的部分for(int row=1;row<m;row++)for(int col=1;col<n;col++){if((row==0||col==0)&&obstacleGrid[row][col]==0) dp[row][col]=1;else if(obstacleGrid[row][col]==0)dp[row][col]=dp[row-1][col]+dp[row][col-1];}return dp[m-1][n-1];}
};
