63. 不同路径 II
发布人:shili8
发布时间:2025-03-06 17:35
阅读次数:0
**不同路径 II**
在上一个问题中,我们讨论了如何计算从起点到终点的不同路径数量。然而,这个问题有一个新的挑战:我们需要考虑每条路径上的数字之和。
具体来说,给定一个 m x n 的网格,其中每个单元格都包含一个数字,从0 到9。我们的任务是计算从左上角到右下角的不同路径数量,每条路径上的数字之和等于给定的目标值。
**示例**
假设我们有一个3x7 的网格:
[ [1,2,3], [4,5,6], [7,8,9] ]
如果我们的目标值是10,我们需要计算从左上角到右下角的不同路径数量,每条路径上的数字之和等于10。
**解决方案**
这个问题可以使用动态规划来解决。我们首先定义一个函数 `dp(i,j)`,表示从网格的第 i 行、第 j 列开始的不同路径数量,每条路径上的数字之和等于目标值。
我们的目标是计算 `dp(0,0)`,因为这是从左上角到右下角的不同路径数量。
我们可以使用以下递归公式来计算 `dp(i,j)`:
dp(i,j) = dp(i-1,j-1) + dp(i-1,j)
这个公式意味着,我们可以从网格的第 i 行、第 j 列开始,向左或向上移动一步,然后继续走路。
然而,这个递归公式有一个问题:它会导致重复计算。例如,如果我们计算 `dp(0,0)`,然后再次计算 `dp(1,0)`,我们就会重复计算 `dp(0,0)`。
为了解决这个问题,我们可以使用记忆化技术。我们创建一个缓存数组 `cache`,其中每个元素代表从网格的某一行、某一列开始的不同路径数量,每条路径上的数字之和等于目标值。
当我们计算 `dp(i,j)` 时,我们首先检查缓存数组中是否有相应的值。如果有,我们直接返回这个值。否则,我们使用递归公式计算 `dp(i,j)}`,然后将结果存储在缓存数组中。
**代码示例**
def uniquePathsWithSum(grid, target): m, n = len(grid), len(grid[0]) cache = [[-1 for _ in range(n)] for _ in range(m)] def dp(i, j): if i == m and j == n: return1 if grid[i][j] == target else0 if i >= m or j >= n: return0 if cache[i][j] != -1: return cache[i][j] res = dp(i+1, j) + dp(i, j+1) cache[i][j] = res return res return dp(0,0) grid = [ [1,2,3], [4,5,6], [7,8,9] ] target =10print(uniquePathsWithSum(grid, target)) # Output:1
**注释**
* 我们使用一个缓存数组 `cache` 来记忆化计算结果。
* 每个元素代表从网格的某一行、某一列开始的不同路径数量,每条路径上的数字之和等于目标值。
* 当我们计算 `dp(i,j)` 时,我们首先检查缓存数组中是否有相应的值。如果有,我们直接返回这个值。否则,我们使用递归公式计算 `dp(i,j)}`,然后将结果存储在缓存数组中。
**时间复杂度**
* 最坏情况下,我们需要计算从左上角到右下角的不同路径数量,每条路径上的数字之和等于目标值。
* 每个元素代表从网格的某一行、某一列开始的不同路径数量,每条路径上的数字之和等于目标值。
* 我们使用递归公式计算 `dp(i,j)}`,然后将结果存储在缓存数组中。
* 因此,时间复杂度为 O(m * n),其中 m 和 n 是网格的行数和列数。
**空间复杂度**
* 我们使用一个缓存数组 `cache` 来记忆化计算结果。
* 每个元素代表从网格的某一行、某一列开始的不同路径数量,每条路径上的数字之和等于目标值。
* 因此,空间复杂度为 O(m * n),其中 m 和 n 是网格的行数和列数。