leetcode:980. 不同路径 III

题目来源

题目描述

在这里插入图片描述

class Solution {
public:
    int uniquePathsIII(vector<vector<int>>& grid) {

    }
};

题目解析

题意

  • 每个无障碍方格都要通过一次把所有能走的格子都走完而且刚好到达终点的路径
  • 每个格子只能都一次,意味着不能走回头路

在这里插入图片描述

那么:怎么判断是否已经走完了所有格子呢?

  • 可以统计所有可以通过的格子数量,假设为count。
  • 然后正常的回溯,当步骤为count + 1时,(到达终点的步数正是走完了所有可通过格子再加一),如果当前刚好在终点上,那么就形成了有效路径。

怎么做到不走回头路呢?

  • 当到达一个可走的格子时,需要先标记它已经走过。在四个方向都尝试完了之后,才恢复现场
class Solution {
    std::vector<std::vector<int>> directions {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//四个方向



    /**
   * @param x     坐标的row
   * @param y     坐标的col
   * @param counts 当前路径所剩的长度
   * @param grid  矩阵
   * @return
   */
    int dfs(int x, int y, int counts, vector<vector<int>>& grid){
        int m = grid.size(), n = grid[0].size();
        // 切记 不合法索引一定要从头就掐除,因为它最容易导致报错;
        // 当前位置是障碍(即值为 -1)跳出;
        if (x < 0 || x == m || y < 0 || y == n || grid[x][y] == -1)
            return 0;//其中的-1表示是原矩阵的-1

        if (grid[x][y] == 2) {
            //这一句很关键,paths表示当前剩下的路径的长度,其为0表示已经走完了,开始收集,return 1 在原来的res基础上加上这个方案
            //当然有场景是未走完全部的0后,到达2这个终点的,这时候并不开始计算路径,因为paths不是0,表示没有全部走完0这种点,return 0 加上后对结果影响
            return counts == 0 ? 1 : 0;
        }

        grid[x][y] = -1;//如果当前的位置未被走过,标记为-1表示已经走过
        int res = 0;
        for (auto & direction : directions) {//四个方向的结果都走,res+注意
            res += dfs(x + direction[0], y + direction[1], counts - 1, grid);
        }
        grid[x][y] = 0;//恢复当前的位置表示可走
        return res;
    }

public:
    int uniquePathsIII(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();

        int X = 0, Y = 0, counts = 1;   //开始时的坐标轴(X,Y)及路径长度(初始化时为1,因为1本身也可以走)
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if(grid[i][j] == 1){
                    X = i;
                    Y = j;
                }else if(grid[i][j] == 0){
                    counts++;
                }
            }
        }

        return dfs(X, Y, counts, grid);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值