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
Given an m x n
integer array grid
representing a grid where:
1
represents the starting square.2
represents the ending square.0
represents empty squares.-1
represents obstacles.Find the number of 4-directional walks from the starting square to the ending square that walk over every non-obstacle square exactly once.
This problem can be efficiently solved using a backtracking algorithm. The core idea is to explore all possible paths from the starting point to the ending point, keeping track of visited cells. We only consider valid paths that visit every non-obstacle cell exactly once.
Initialization:
start_row
, start_col
) and the ending coordinates.empty_count
). This helps us determine if a path is complete.Backtracking Function (dfs
):
dfs(row, col, visited_count)
: This recursive function takes the current row and column, and the number of visited cells as input.grid[row][col] == 2
):
visited_count
equals empty_count + 1
(all empty cells and the start cell have been visited), we found a valid path, so return 1.grid[neighbor_row][neighbor_col] != -1
), and not already visited.dfs
on the neighbor.Main Function:
dfs
function starting from the start_row
, start_col
, and an initial visited_count
of 0.visited_count
check.visited
set (or similar data structure to track visited cells).def uniquePathsIII(grid):
rows, cols = len(grid), len(grid[0])
start_row, start_col = -1, -1
empty_count = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == 1:
start_row, start_col = r, c
elif grid[r][c] == 0:
empty_count += 1
def dfs(row, col, visited_count):
if grid[row][col] == 2:
return 1 if visited_count == empty_count + 1 else 0
count = 0
for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
new_row, new_col = row + dr, col + dc
if 0 <= new_row < rows and 0 <= new_col < cols and grid[new_row][new_col] != -1:
temp = grid[new_row][new_col]
grid[new_row][new_col] = -1 # Mark as visited (temporarily)
count += dfs(new_row, new_col, visited_count + 1)
grid[new_row][new_col] = temp # Backtrack
return count
return dfs(start_row, start_col, 0)
The code in other languages (Java, C++, Go, TypeScript, JavaScript) follows a very similar structure, using the same backtracking approach. The primary difference lies in syntax and data structure choices. The core logic remains consistent.