[バックトラッキング] [リートコード]始点から終点までのすべてのパスの数

トピック:

2次元グリッドには、次の4種類のグリッドがあります。

  • 1は開始正方形を表します。そして、開始広場は1つだけです。
  • 2は端の正方形を意味し、端の正方形は1つだけです。
  • 0は、通り抜けることができる空の正方形を意味します。
  • -1は私たちが克服できない障害を意味します。

4つの方向(上、下、左、右)に歩いたときに、開始正方形から終了正方形までのさまざまなパスの数を返します。

バリアフリーの各正方形は1回通過する必要がありますが、同じ正方形をパスで繰り返すことはできません

例1:

入力:[[1,0,0,0]、[0,0,0,0]、[0,0,2、-1]]
出力:2
説明:次の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)を見つけ、空の正方形の数を数え、それをターゲットとして記録し、現在通過した正方形の数を記録する変数currentを定義し、1から累積します(デフォルトの開始点を通過しました) )。

  • 再帰的な終了条件/結果は条件を満たします:渡された正方形の数=空の正方形の数+ 2(1つの開始点、1つの終了点)
  • 再帰呼び出し条件:上、下、左、右の正方形の場合、0の場合は再帰し、2(つまり終点)の場合は、すべての空の正方形をトラバースしたときにのみ再帰します。条件を満たさないものは剪定されたと見なされます。

この質問は結果の数のみを出力し、結果リストは出力しないため、パスパスを定義せず、グリッド上で直接変更します。再帰の前に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