Java 中计算给定矩阵中的路径数量

10 Sept 2024 | 4 分钟阅读

计算机科学中的一个典型问题是计算给定矩阵中的路径数量,这可以通过多种方法来解决。在本节中,我们将讨论使用 Java 计算给定矩阵中路径的三种不同方法。

问题陈述

我们给出了一个二维矩阵,它类似于一个网格。网格由非负整数组成,网格中的每个单元格表示通过它的成本。您的任务是计算从矩阵的左上角到右下角仅沿一个方向移动的可能路线的数量。

输入

  1. 一个大小为 m x n 的二维矩阵 (1 <= m, n <= 100)。
  2. 每个单元格 matrix[i][j] 表示该单元格的成本。您可以假设所有值都是非负的。

输出

  1. 一个表示唯一路径总数的整数。

方法 1:递归

  1. 定义一个名为 countPathsRecursive() 的方法,该方法以矩阵和当前位置 (row, col) 作为参数。
  2. 检查 (row, col) 是否为目标。如果是,则返回 1。
  3. 检查 (row, col) 是否超出矩阵边界。如果是,则返回 0。
  4. 调用 countPathsRecursive() 来向右 (row, col + 1) 和向下 (row + 1, col) 移动。
  5. 将递归调用获得的结果相加。
  6. 在 main 方法中,初始化矩阵并使用起始位置 (0, 0) 调用 countPathsRecursive()。

MatrixPathCount.java

输出

Number of paths: 6

方法 2:动态规划(记忆化)

  1. 创建一个名为 countPathsMemoization() 的方法,该方法以矩阵、当前位置和记忆化表 (memo) 作为参数。
  2. 初始化一个与矩阵尺寸相匹配的二维记忆化表 (memo)。
  3. 在递归调用之前检查 memo[row][col]。
  4. 如果 memo[row][col] 不为零,则返回其值。
  5. 记忆化递归调用的结果。
  6. 调用 countPathsMemoization() 来向右和向下移动。
  7. 将递归调用获得的结果相加。
  8. 在 main 方法中,初始化矩阵和记忆化表,并使用起始位置 (0, 0) 调用 countPathsMemoization()。

MatrixPathCount.java

输出

Number of paths: 6

方法 3:动态规划(制表)

  1. 创建一个名为 countPathsTabulation() 的方法,该方法以矩阵作为参数。
  2. 创建一个与矩阵尺寸相匹配的二维动态规划表 (dp)。
  3. 基于到达这些行/列中每个单元格只有一种方式这一事实,初始化 DP 表的最右列和最下行。
  4. 从倒数第二行和倒数第二列开始,自下而上遍历矩阵。
  5. 根据递归公式填充 DP 表:dp[i][j] = dp[i + 1][j] + dp[i][j + 1]。
  6. 结果存储在 dp[0][0] 中。
  7. 在 main() 方法中,初始化矩阵并调用 countPathsTabulation()。

MatrixPathCount.java

输出

Number of paths: 6

结论

总而言之,有几种方法可以解决给定矩阵中的路径计数问题,每种方法都有其独特的权衡。尽管概念上很简单,但递归方法对于较大的矩阵会变得无效,因为它涉及重复计算。无论是通过制表还是记忆化,动态规划都通过简化计算过程来克服这种低效率。

通过使用记忆化表来存储和检索先前计算的结果,记忆化技术大大减少了重复计算并提高了生产力。当存在重叠子问题且递归对于解决问题有意义时,此方法特别有用。

另一方面,制表方法使用自下而上的动态规划表来迭代填充值,完全避免了递归的开销。虽然这种方法很有效,但它需要额外的空间来存储动态表。