【回溯】【leetcode】起点到终点的所有路径数量

题目:

在二维网格 grid 上,有 4 种类型的方格:

  • 1 表示起始方格。且只有一个起始方格。
  • 2 表示结束方格,且只有一个结束方格。
  • 0 表示我们可以走过的空方格。
  • -1 表示我们无法跨越的障碍。

返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目。

每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格

示例 1:

输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
输出:2
解释:我们有以下两条路径:
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)

来源:

980. 不同路径 III

解题思路:回溯

先找到起始位置(x,y),并统计空方格的数量,记作target,定义一个变量current记录当前经过的方格数量,从1开始累计(默认起点已遍历)。

  • 递归终止条件/结果满足条件:经过的方格数量=空方格数量+2(1个起点,1个终点)
  • 递归调用条件:针对上下左右方格,如果是0则递归;如果是2(即终点)仅当所有空方格遍历完成时递归。不满足条件的认为被剪枝。

本题只输出结果数量不输出结果列表,所以不再定义路径path,直接在grid上修改:递归前设置为x(只要不是0,1,2,-1即可),递归后复原。

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

        // 找出起始方格,统计空方格个数
        int target = 0;
        int x = 0, y = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0) target++;
                if (grid[i][j] == 1) {
                    x = i;
                    y = j;
                }
            }
        }
        result = 0;
        back(grid, x, y, 1, target+2);
        return result;
    }
    void back(vector<vector<int>>& grid, int x, int y, int current, int target) {
        if (current == target) {
            result++;
            return;
        }
        // 上下左右
        if (x > 0) {
            int t = grid[x-1][y];
            if (t == 0 || (current + 1 == target && t == 2)) {
                grid[x-1][y] = 3;
                back(grid, x-1, y, current+1, target);
                grid[x-1][y] = t;
            }
        }
        if (x + 1 < m) {
            int t = grid[x+1][y];
            if (t == 0 || (current + 1 == target && t == 2)) {
                grid[x+1][y] = 3;
                back(grid, x+1, y, current+1, target);
                grid[x+1][y] = t;
            }
        }
        if (y > 0) {
            int t = grid[x][y-1];
            if (t == 0 || (current + 1 == target && t == 2)) {
                grid[x][y-1] = 3;
                back(grid, x, y-1, current+1, target);
                grid[x][y-1] = t;
            }
        }
        if (y + 1 < n) {
            int t = grid[x][y+1];
            if (t == 0 || (current + 1 == target && t == 2)) {
                grid[x][y+1] = 3;
                back(grid, x, y+1, current+1, target);
                grid[x][y+1] = t;
            }
        }
    }
};

猜你喜欢

转载自blog.csdn.net/hbuxiaoshe/article/details/115082160