980. Unique Paths III
Description
You are given an m x n
integer array grid
where grid[i][j]
could be:
1
representing the starting square. There is exactly one starting square.2
representing the ending square. There is exactly one ending square.0
representing empty squares we can walk over.-1
representing obstacles that we cannot walk over.
Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.
Example 1:
Input: grid = [[1,0,0,0],[0,0,0,0],[0,0,2,-1]] Output: 2 Explanation: We have the following two paths: 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)
Example 2:
Input: grid = [[1,0,0,0],[0,0,0,0],[0,0,0,2]] Output: 4 Explanation: We have the following four paths: 1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3) 2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3) 3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3) 4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)
Example 3:
Input: grid = [[0,1],[2,0]] Output: 0 Explanation: There is no path that walks over every empty square exactly once. Note that the starting and ending square can be anywhere in the grid.
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 20
1 <= m * n <= 20
-1 <= grid[i][j] <= 2
- There is exactly one starting cell and one ending cell.
Solutions
Solution: Backtracking
- Time complexity: O(4mn)
- Space complexity: O(mn)
JavaScript
js
/**
* @param {number[][]} grid
* @return {number}
*/
const uniquePathsIII = function (grid) {
const START = 1;
const END = 2;
const OBSTACLE = -1;
const m = grid.length;
const n = grid[0].length;
const totalCell = m * n;
const startPoint = { row: -1, col: -1 };
let obstacles = 0;
const walkGrid = (row, col, step) => {
if (row < 0 || col < 0 || row >= m || col >= n) return 0;
const value = grid[row][col];
if (value === END) {
return step === totalCell - obstacles ? 1 : 0;
}
if (value === '.' || value === OBSTACLE) return 0;
const nextStep = step + 1;
grid[row][col] = '.';
const left = walkGrid(row, col - 1, nextStep);
const right = walkGrid(row, col + 1, nextStep);
const up = walkGrid(row - 1, col, nextStep);
const down = walkGrid(row + 1, col, nextStep);
grid[row][col] = value;
return left + right + up + down;
};
for (let row = 0; row < m; row++) {
for (let col = 0; col < n; col++) {
const value = grid[row][col];
if (value === OBSTACLE) {
obstacles += 1;
}
if (value === START) {
startPoint.row = row;
startPoint.col = col;
}
}
}
return walkGrid(startPoint.row, startPoint.col, 1);
};