【leedcode】576. 出界的路径数

226 阅读1分钟

这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

难度: 中等

题目描述

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

给你五个整数 m、n、maxMove、startRow 以及 startColumn ,找出并返回可以将球移出边界的路径数量。因为答案可能非常大,返回对 109 + 7 取余 后的结果。

示例 1:

image.png

输入:m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0 输出:6

示例 2:

image.png

输入:m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1 输出:12  

提示:

1 <= m, n <= 50 0 <= maxMove <= 50 0 <= startRow < m 0 <= startColumn < n

解题思路

  • 最直接的方式是DFS递归解决,只要出界,那就是有一种结果,return 1return1,

  • 否则就递归求解。但是直接递归,存在大量的重复计算,比如考虑移动kk步和移动k-1k−1步的时候,就可以有1步选择不同的位置出界(其实也可以选更多不同的步数)。

  • 如果要采用递归的方式,应当考虑采用记忆化的方法,python提供了 @lru_cache(None) 装饰器,可以实现备忘的功能,加上 @lru_cache(None) 的代码和执行结果如下。

  • 还有一种思考方式是使用动态规划,既然写出了递归,那么可以根据递归来改写成动态规划。

for di, dj in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]:
    count=(count + self.findPaths(m, n, N-1, di, dj)) % 1000000007

这样就把递归深搜改写成了动态规划。

记忆化递归

class Solution:
    @lru_cache(None)  #通过修饰器实现记忆化
    def findPaths(self, m: int, n: int, N: int, i: int, j: int) -> int:
        count = 0
        if N < 0:
            return count
        if i < 0 or i >= m or j < 0 or j >= n:
            return 1
        for m, n in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]:
            count = (count + self.findPaths(m, n, N-1, m, n)) % 1000000007
        return count

动态规划

class Solution:
    def findPaths(self, m: int, n: int, N: int, i: int, j: int) -> int:
        dp = [[[0]*(n+2) for _ in range(m+2)] for _ in range(N+1)]
        if N == 0:
            return 0
        for k in range(N+1):
            for x in range(m+2):
                for y in range(n+2):
                    if x == 0 or y == 0 or x == m + 1 or y == n + 1: #相当于递归的基线条件
                        dp[k][x][y] = 1
                    else:
                        if k == 0:
                            continue
                        else:  # 相当于递归调用部分
                            dp[k][x][y] = (dp[k][x][y] + dp[k-1][x-1][y] + \
                                        dp[k-1][x+1][y] + dp[k-1][x][y-1] + \
                                        dp[k-1][x][y+1]) % 1000000007
        return dp[N][i+1][j+1]