classSolution: defuniquePathsIII(self, grid: List[List[int]]) -> int: r, c = len(grid), len(grid[0]) si, sj, n = 0, 0, 0 for i inrange(r): for j inrange(c): if grid[i][j] == 0: n += 1 elif grid[i][j] == 1: n += 1 si, sj = i, j
defdfs(i: int, j: int, n: int) -> int: if grid[i][j] == 2: if n == 0: return1 return0 t = grid[i][j] grid[i][j] = -1 res = 0 for di, dj in [[-1, 0], [1, 0], [0, -1], [0, 1]]: ni, nj = i + di, j + dj if0 <= ni < r and0 <= nj < c and grid[ni][nj] in [0, 2]: res += dfs(ni, nj, n - 1) grid[i][j] = t return res
publicintUniquePathsIII(int[][] grid) { int r = grid.Length, c = grid[0].Length; int si = 0, sj = 0, n = 0; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { if (grid[i][j] == 0) { n++; } elseif (grid[i][j] == 1) { n++; si = i; sj = j; } } } return DFS(grid, si, sj, n); }
publicintDFS(int[][] grid, int i, int j, int n) { if (grid[i][j] == 2) { return n == 0 ? 1 : 0; } int r = grid.Length, c = grid[0].Length; int t = grid[i][j]; grid[i][j] = -1; int res = 0; foreach (int[] dir in dirs) { int ni = i + dir[0], nj = j + dir[1]; if (ni >= 0 && ni < r && nj >= 0 && nj < c && (grid[ni][nj] == 0 || grid[ni][nj] == 2)) { res += DFS(grid, ni, nj, n - 1); } } grid[i][j] = t; return res; } }
var uniquePathsIII = function(grid) { const r = grid.length, c = grid[0].length; let si = 0, sj = 0, n = 0; for (let i = 0; i < r; i++) { for (let j = 0; j < c; j++) { if (grid[i][j] === 0) { n++; } elseif (grid[i][j] === 1) { n++; si = i; sj = j; } } } returndfs(grid, si, sj, n); };
functiondfs(grid, i, j, n) { if (grid[i][j] === 2) { return n === 0 ? 1 : 0; } const r = grid.length, c = grid[0].length, t = grid[i][j]; grid[i][j] = -1; let res = 0; for (const dir of dirs) { const ni = i + dir[0], nj = j + dir[1]; if (ni >= 0 && ni < r && nj >= 0 && nj < c && (grid[ni][nj] === 0 || grid[ni][nj] === 2)) { res += dfs(grid, ni, nj, n - 1); } } grid[i][j] = t; return res; }
classSolution: defuniquePathsIII(self, grid: List[List[int]]) -> int: r, c = len(grid), len(grid[0]) si, sj, st = 0, 0, 0 for i inrange(r): for j inrange(c): if grid[i][j] in [0, 2]: st |= (1 << (i * c + j)) elif grid[i][j] == 1: si, sj = i, j
@lru_cache(None) defdp(i: int, j: int, st: int) -> int: if grid[i][j] == 2: if st == 0: return1 return0 res = 0 for di, dj in [[-1, 0], [1, 0], [0, -1], [0, 1]]: ni, nj = i + di, j + dj if0 <= ni < r and0 <= nj < c and (st & (1 << (ni * c + nj))) > 0: res += dp(ni, nj, st ^ (1 << (ni * c + nj))) return res
publicintUniquePathsIII(int[][] grid) { int r = grid.Length, c = grid[0].Length; int si = 0, sj = 0, st = 0; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { if (grid[i][j] == 0 || grid[i][j] == 2) { st |= 1 << (i * c + j); } elseif (grid[i][j] == 1) { si = i; sj = j; } } } return DP(grid, si, sj, st); }
publicintDP(int[][] grid, int i, int j, int st) { if (grid[i][j] == 2) { return st == 0 ? 1 : 0; } int r = grid.Length, c = grid[0].Length; int key = ((i * c + j) << (r * c)) + st; if (!memo.ContainsKey(key)) { int res = 0; foreach (int[] dir in dirs) { int ni = i + dir[0], nj = j + dir[1]; if (ni >= 0 && ni < r && nj >= 0 && nj < c && (st & (1 << (ni * c + nj))) > 0) { res += DP(grid, ni, nj, st ^ (1 << (ni * c + nj))); } } memo.Add(key, res); } return memo[key]; } }
classSolution { public: intuniquePathsIII(vector<vector<int>>& grid){ int r = grid.size(), c = grid[0].size(); int si = 0, sj = 0, st = 0; unordered_map<int, int> memo; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { if (grid[i][j] == 0 || grid[i][j] == 2) { st |= (1 << (i * c + j)); } elseif (grid[i][j] == 1) { si = i, sj = j; } } }
function<int(int ,int, int)> dp = [&](int i, int j, int st) -> int { if (grid[i][j] == 2) { if (st == 0) { return1; } return0; } int key = ((i * c + j) << (r * c)) + st; if (!memo.count(key)) { int res = 0; vector<array<int, 2>> dir({{-1, 0}, {1, 0}, {0, -1}, {0, 1}}); for (auto &[di, dj] : dir) { int ni = i + di, nj = j + dj; if (ni >= 0 && ni < r && nj >= 0 && nj < c && (st & (1 << (ni * c + nj))) > 0) { res += dp(ni, nj, st ^ (1 << (ni * c + nj))); } } memo[key] = res; } return memo[key]; }; returndp(si, sj, st); } };
intdp(int i, int j, int st, int** grid, int r, int c, HashItem **memo) { if (grid[i][j] == 2) { if (st == 0) { return1; } return0; } int key = ((i * c + j) << (r * c)) + st; if (!hashFindItem(memo, key)) { int res = 0; for (int k = 0; k < 4; k++) { int ni = i + dir[k][0], nj = j + dir[k][1]; if (ni >= 0 && ni < r && nj >= 0 && nj < c && (st & (1 << (ni * c + nj))) > 0) { res += dp(ni, nj, st ^ (1 << (ni * c + nj)), grid, r, c, memo); } } hashAddItem(memo, key, res); } return hashGetItem(memo, key, 0); }
intuniquePathsIII(int** grid, int gridSize, int* gridColSize) { int r = gridSize, c = gridColSize[0]; int si = 0, sj = 0, st = 0; HashItem *memo = NULL; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { if (grid[i][j] == 0 || grid[i][j] == 2) { st |= (1 << (i * c + j)); } elseif (grid[i][j] == 1) { si = i, sj = j; } } } int ret = dp(si, sj, st, grid, r, c, &memo); hashFree(&memo); return ret; }
var dir = [4][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}
funcuniquePathsIII(grid [][]int)int { r, c := len(grid), len(grid[0]) si, sj, st := 0, 0, 0 memo := map[int]int{} for i := 0; i < r; i++ { for j := 0; j < c; j++ { if grid[i][j] == 0 || grid[i][j] == 2 { st |= (1 << (i * c + j)) } elseif grid[i][j] == 1 { si, sj = i, j } } }
var dp func(i int, j int, st int)int dp = func(i int, j int, st int)int { if grid[i][j] == 2 { if st == 0 { return1 } return0 } key := ((i * c + j) << (r * c)) + st res, ok := memo[key] if !ok { res = 0 for k := 0; k < 4; k++ { ni, nj := i + dir[k][0], j + dir[k][1] if ni >= 0 && ni < r && nj >= 0 && nj < c && (st & (1 << (ni * c + nj))) > 0 { res += dp(ni, nj, st ^ (1 << (ni * c + nj))) } } memo[key] = res } return res } return dp(si, sj, st) }
复杂度分析
时间复杂度:O(r\times c \times 2^{r\times c}),其中 r 和 c 分别是 grid 的行数和列数。O(r\times c \times 2^{r\times c}) 是状态数,每个状态只会被计算一次,计算一个状态的时间复杂度为 O(1)。