There is an m x n
grid with a ball. The ball is initially at the position [startRow, startColumn]
. You are allowed to move the ball to one of the four adjacent cells in the grid (possibly out of the grid crossing the grid boundary). You can apply at most maxMove
moves to the ball.
Given the five integers m
, n
, maxMove
, startRow
, startColumn
, return the number of paths to move the ball out of the grid boundary. Since the answer can be very large, return it modulo 109 + 7
.
Example 1:
Input: m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0 Output: 6
Example 2:
Input: m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1 Output: 12
Constraints:
1 <= m, n <= 50
0 <= maxMove <= 50
0 <= startRow < m
0 <= startColumn < n
This problem asks to find the number of paths a ball can take from a starting position in a grid to move out of the grid's boundaries within a given number of moves. The solution uses dynamic programming with memoization to efficiently count these paths.
The core idea is to use a recursive depth-first search (DFS) function to explore all possible paths. Memoization is crucial to avoid redundant calculations, significantly improving performance.
The dfs(i, j, k)
function represents the number of paths to go out of bounds from position (i, j)
with k
moves remaining.
Base Cases:
(i, j)
is out of bounds (i.e., i < 0
or i >= m
or j < 0
or j >= n
), we've left the grid. We return 1
if we still have moves (k >= 0
), indicating a successful path, otherwise 0
.k <= 0
, we've run out of moves without leaving the grid, so we return 0
.Memoization:
f[i][j][k]
(or a similar data structure depending on the language) to store the results of previous dfs
calls. If f[i][j][k]
is not null
or -1
(depending on the initialization), we directly return the stored value.Recursive Step:
dfs
with the updated position and remaining moves (k - 1
).10^9 + 7
to handle large results.Main Function:
dfs
with the starting position and maximum number of moves.Time Complexity: O(m * n * maxMove). The dfs
function is called at most once for each combination of (i, j, k)
, where 0 <= i < m
, 0 <= j < n
, and 0 <= k <= maxMove
. This gives a total of m * n * (maxMove + 1)
possible combinations. Memoization ensures that each combination is only evaluated once.
Space Complexity: O(m * n * maxMove). The space is dominated by the memoization array f
, which stores the results of previous dfs
calls.
The code examples provided in the original response accurately implement this approach in multiple languages. The Python code uses @cache
decorator (from functools
), a concise way to add memoization in Python. Other languages use explicit 3D arrays to manage the memoization. All of them follow the same algorithmic structure described above.