LeetCode 576. Out of Boundary Paths

369 阅读1分钟

LeetCode 576. Out of Boundary Paths

给你一个大小为 m x n 的网格和一个球。球的起始坐标为 [startRow, startColumn] 。你可以将球移到在四个方向上相邻的单元格内(可以穿过网格边界到达网格之外)。你 最多 可以移动 maxMove 次球。

给你五个整数 mnmaxMovestartRow 以及 startColumn ,找出并返回可以将球移出边界的路径数量。因为答案可能非常大,返回对 109 + 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

算法

(动态规划) O(N⋅m⋅n) 定义状态 f(k,x,y) 表示从网格边界格子经过 k 步,到达格子 (x, y) 的方案数。 初始时,每个位于边界的格子 (x, y),其 f(0,x,y)=1;转移时,每个点可以从四个相邻的格子(如果存在)进行累加转移。 最终答案为,f(0,i,j)+f(1,i,j)+…+f(N−1,i,j)。由于规定边界的格子步数为 0,所以最多只能统计到 N−1步。

时间复杂度

状态数为 O(N⋅m⋅n),每个状态的转移数为 O(1),故总时间复杂度为 O(N⋅m⋅n)。

C++ 代码

class Solution {
public:
    int mod = 1000000007;
    int dx[4] = {0, 1, 0, -1};
    int dy[4] = {1, 0, -1, 0};

    int findPaths(int m, int n, int N, int i, int j) {
        if (N == 0)
            return 0;
        vector<vector<vector<int>>> f(N, vector<vector<int>>(m, vector<int>(n, 0)));

        for (int x = 0; x < m; x++) {
            f[0][x][0] ++;
            f[0][x][n - 1]++;
        }

        for (int y = 0; y < n; y++) {
            f[0][0][y]++;
            f[0][m - 1][y]++;
        }

        for (int k = 1; k < N; k++)
            for (int x = 0; x < m; x++)
                for (int y = 0; y < n; y++)
                    for (int t = 0; t < 4; t++) {
                        int u = x + dx[t], v = y + dy[t];
                        if (u < 0 || u >= m || v < 0 || v >= n)
                            continue;
                        f[k][x][y] = (f[k][x][y] + f[k - 1][u][v]) % mod;
                    }
        int ans = 0;
        for (int k = 0; k < N; k++)
            ans = (ans + f[k][i][j]) % mod;
        return ans;
    }
};