LeetCode——576. 出界的路径数[Out of Boundary Paths][中等]——分析及代码[Java]
一、题目
给你一个大小为 m x n 的网格和一个球。球的起始坐标为 [startRow, startColumn] 。你可以将球移到在四个方向上相邻的单元格内(可以穿过网格边界到达网格之外)。你 最多 可以移动 maxMove 次球。
给你五个整数 m、n、maxMove、startRow 以及 startColumn ,找出并返回可以将球移出边界的路径数量。因为答案可能非常大,返回对 10^9 + 7 取余 后的结果。
示例 1:
输入:m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0
输出:6
示例 2:
输入:m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1
输出:12
提示:
- 1 <= m, n <= 50
- 0 <= maxMove <= 50
- 0 <= startRow < m
- 0 <= startColumn < n
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/out-of-boundary-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、分析及代码
1. 动态规划
(1)思路
根据题目特点,球每次只能向上、下、左、右 4 个固定的方向移动 1 格,可结合动态规划方法求解。
设计一个二维数组 dp,其中 dp[i][j] 表示当前以坐标 (i, j) 为终点的路径数量。在每个移动步中,统计可将球移出边界的路径数量,并根据本步移动情况更新 dp,直至用完所有移动次数。
(2)代码
class Solution {
int m, n;
int mod = (int)1e9 + 7;
int[][] move = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};//移动方向
public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
//初始化
this.m = m;
this.n = n;
long ans = 0;
long[][] dp = new long[m][n];//dp[i][j]表示当前以坐标(i, j)为终点的路径数量
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
dp[i][j] = 0;
dp[startRow][startColumn] = 1;//初始化起点
//动态规划
for (int step = 0; step < maxMove; step++) {
//统计当前移动步中,可以将球移出边界的路径数量
for (int i = 0; i < m; i++)//上一移动步结束后,位于左右边界的路径,可在当前移动步中出界
ans = (ans + dp[i][0] + dp[i][n - 1]) % mod;
for (int j = 0; j < n; j++)//上一移动步结束后,位于上下边界的路径,可在当前移动步中出界
ans = (ans + dp[0][j] + dp[m - 1][j]) % mod;
//统计完成当前移动步后,以网格中各位置为终点的路径数量
long[][] nextDp = new long[m][n];//nextDp[i][j]表示当前移动步结束后,以坐标(i, j)为终点的路径数量
for (int i = 0; i < m; i++) {//遍历纵坐标
for (int j = 0; j < n; j++) {//遍历横坐标
for (int k = 0; k < 4; k++) {//遍历4个移动方向
int x = i + move[k][0], y = j + move[k][1];//上一步可能的所处位置
if (inGrid(x, y))//判断该位置有效性
nextDp[i][j] = (nextDp[i][j] + dp[x][y]) % mod;//添加从(x,y)移动到当前位置(i,j)的路径数量
}
}
}
for (int i = 0; i < m; i++)//复制nextDp到dp
for (int j = 0; j < n; j++)
dp[i][j] = nextDp[i][j];
}
return (int)ans;
}
//判断当前位置是否在网格内
public boolean inGrid(int x, int y) {
return x >= 0 && x < m && y >= 0 && y < n;
}
}
(3)结果
执行用时 :12 ms,在所有 Java 提交中击败了 56.09% 的用户;
内存消耗 :37.5 MB,在所有 Java 提交中击败了 73.19% 的用户。
三、其他
暂无。