DP一遍过无剪枝 -- 解题思路:
类似题:62不同路径
在类似题中,用dp[i][j]表示到达(i, j)的方案数
联想到 => 用dp[i][j]表示这条路能否走
验证:用dp[i][j]表示解的状态(下标(i,j)是否在解的路径上)
首先如果起点或者终点就是障碍,那么直接不可能有解的路径
设定了状态,找状态转移方程:
如果dp[i][j] == 1,即dp[i][j]本来就是障碍,那么直接走不通,无需考虑
如果dp[i][j] == 0,就有如下考虑:
设n = 行数, m = 列数
1.当i == n - 1 && j == m - 1时,终点,直接过
2.当i == n - 1时,它只能往右走,那么dp[i][j]的状态就取决于dp[i][j + 1],如果右边走不通,这个点也就不在解的路径上,这时就将这个点置1
3.当j == m - 1时,它只能往下走,那么dp[i][j]的状态就取决于dp[i + 1][j],如果右边走不通,这个点也就不在解的路径上,这时就将这个点置1
4.其他情况,机器人可以往右走或者往下走,那么dp[i][j]的状态就取决于dp[i][j + 1]或者dp[i + 1][j],如果右边和下边都走不通,那么(i, j)也就不在解的路径上,那么我们也可以将它看成障碍。如果左边或者右边有一个点走得通,那么(i, j)就在解的路径上。
所以状态转移方程为:
dp[i][j] == 1,直接忽略
dp[i][j] == 0,分情况考虑:
1.i == n - 1 && j == m - 1 , 忽略
2.i == n - 1 : dp[i][j] = dp[i][j + 1] 只能往右走
3.j == m - 1 : dp[i][j] = dp[i + 1][j] 只能往下走
4.其他 : dp[i][j] = dp[i + 1][j] & dp[i][j + 1] 可以往下走也可以往右走
这样遍历完,我们就可以判断dp[0][0]是否为1判定是否有解:
无解,直接返回空数组
有解,dfs寻找路径:
寻找路径时,因为dp[i][j] == 0就代表这个点一定在其中一条路径上,而我们只需要求一条路径,所以我们我们只需判断往下走或者往右走即可。
PS:这里说一下DP遍历时 i, j 从大到小还是从小到大的问题,这个取决于状态转移方程,如果当前状态取决于 i + 1,那么i 就是从大到小,对j也是如此。反之亦然。
代码以及注释如下:
class Solution {
public:
vector<vector<int>> res;
void dfs(vector<vector<int>>& dp, int i, int j){
int n = dp.size(), m = dp[0].size();
res.push_back({i, j});
if(i == n - 1 && j == m - 1) return ;
//我们只要找到一条路径就行,所以只要一个条件通了就完成了,0的路径就是解
if(i < n - 1 && dp[i + 1][j] == 0) dfs(dp, i + 1, j);
else if(j < m - 1 && dp[i][j + 1] == 0) dfs(dp, i, j + 1);
}
vector<vector<int>> pathWithObstacles(vector<vector<int>>& obstacleGrid){
int n = obstacleGrid.size(), m = obstacleGrid[0].size();
if(obstacleGrid[0][0] == 1 || obstacleGrid[n - 1][m - 1] == 1) return {}; //起点或者终点为1,直接走不通
vector<vector<int>> dp = obstacleGrid;
for(int i = n - 1; i >= 0; i--){
for(int j = m - 1; j >= 0; j--){ //状态转移方程
if((i == n - 1 && j == m - 1) || dp[i][j] == 1) continue;
if(i == n - 1) dp[i][j] = dp[i][j + 1];
else if(j == m - 1) dp[i][j] = dp[i + 1][j];
else dp[i][j] = dp[i + 1][j] & dp[i][j + 1];
}
}
if(dp[0][0] == 1) return {}; //说明走不通,直接返回
dfs(dp, 0, 0);
return res;
}
};
作者:spacex-1
链接:https://leetcode-cn.com/problems/robot-in-a-grid-lcci/solution/c-dpyi-bian-guo-si-lu-zheng-li-by-spacex-cr1u/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。