题目描述:
示例 1:

示例 2:

题目分析:
- 可以将球移到在方向上相邻的单元格内。
- 可以向四个方向移动,假设当前坐标(x,y),则移动一次之后的坐标:
- 上移 : (x - 1, y)
- 下移 : (x + 1, y)
- 左移 : (x, y - 1)
- 右移 : (x, y + 1)
- 最多可以移动 maxMove次球。
- 每次移动maxMove - 1,假设当前坐标(x, y),最大移动次数max.
- 上移 : (x - 1, y), max - 1
- 下移 : (x + 1, y), max - 1
- 左移 : (x, y - 1), max - 1
- 右移 : (x, y + 1), max - 1
- max == 0时,不能再移动。
- 找出并返回可以将球移出的路径数量。
- 假设网格大小m x n,当前坐标(x, y),则x < 0 || x > m || y < 0 || y > n代表球出了网格(边界)
- 结合条件2,也就是求max == 0之前,可以令x < 0 || x > m || y < 0 || y > n的移动路径数量
思路:
class Solution {
int mod = (int)1e9+7;
int[][][] dp;
public int findPaths(int m, int n, int max, int startRow, int startColumn) {
dp = new int[m][n][max + 1];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k <= max; k++) {
dp[i][j][k] = -1;
}
}
}
int result = dfs(m, n, startRow, startColumn, max);
return result;
}
public int dfs(int m, int n, int x, int y, int k) {
if (x < 0 || x >= m || y < 0 || y >= n) return 1; // 出边界,满足要求,路径+1;
if (k == 0) return 0; // 最大移动次数为0,该路径不满足要求。
if (dp[x][y][k] != -1) return dp[x][y][k]; // 该起点与最多移动次数情况已经遍历过,减枝。
int result = 0;
result += dfs(m, n, x - 1, y, k - 1); // 上移
result += dfs(m, n, x + 1, y, k - 1); // 下移
result += dfs(m, n, x, y - 1, k - 1); // 左移
result += dfs(m, n, x, y + 1, k - 1); // 右移
result %= mod; // 防止结果太大,取模。
dp[x][y][k] = result; // 记录起点(x,y)为起点,最大移动次数k 情况时 满足要求的路径数量。用于减枝,避免重复递归.
return result;
}
}