トピック:
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)
ソース:
問題解決のアイデア:バックトラック
最初に開始位置(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;
}
}
}
};