20240125-边界外路径

题目要求

有一个m*n的网格,网格中有一个小球。小球初始位置位[startRow,startColumn]。您可以将小球移动到网格中相邻的四个单元格之一(可能会越过网格边界移出网格)。最多可以对小球进行maxMove移动。

给定 m、n、maxMove、startRow、startColumn 这五个整数,返回将小球移出网格边界的路径数。由于答案可能非常大,因此请返回 10^9+7的模数。

Example 1:

 20240125-边界外路径_第1张图片

Input: m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0
Output: 6

Example 2:

 20240125-边界外路径_第2张图片

Input: m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1
Output: 12

思路

这个题目有三个状态:横坐标、纵坐标和可移动的次数,所以我们可以用一个三维的dp数组存储这三个状态或者一个带有三个参数的dp函数。

状态转移关系:在maxMove步之内从(i,j)位置踢出界外的路径数量等于在maxMove-1步之内从(i,j)的相邻位置踢出界外的路径数量之和。(相邻位置多走一步可以到达i,j)

注意处理计算的冗余和基础情况。这里的递归采用的是数组和递归函数相结合的方式。参考labuladong的思路和题解。

代码

class Solution {
public:
    int memo[50][50][51];
    int m, n;

    int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
        this->m = m;
        this->n = n;
        memset(memo, -1, sizeof(memo));
        return dp(maxMove, startRow, startColumn);
    }

    int dp(int maxMove, int i, int j) {
        // base case,找到一条出界路径
        if (i < 0 || j < 0 || i >= m || j >= n) {
            return 1;
        }
        // 避免冗余计算
        if (memo[i][j][maxMove] != -1) {
            return memo[i][j][maxMove];
        }
        // 无法在有限的步数内出界
        if (maxMove == 0) {
            return 0;
        }
        // 状态转移关系:
        // 在maxMove步之内从(i,j)踢出界外的路径数量等于
        // 在maxMove-1步之内从(i,j)的相邻位置出界的路径数量之和;
        long res = 0;
        res += dp(maxMove - 1, i-1, j);
        res += dp(maxMove - 1, i+1, j);
        res += dp(maxMove - 1, i, j-1);
        res += dp(maxMove - 1, i, j+1);
        memo[i][j][maxMove] = (int)(res % 1000000007);
        return memo[i][j][maxMove];
    }
};

20240125-边界外路径_第3张图片

你可能感兴趣的:(Leetcode每日题解,leetcode,算法,数据结构,动态规划)