返回

简介

人工智能

LeetCode 62:探索动态规划之外的更优解法

LeetCode 62 题,Unique Paths,是一道经典的动态规划问题。它要求我们在一个 m×n 的网格中,从左上角走到右下角,并统计有多少条不同的路径。乍一看,动态规划似乎是解决此问题的最直接方法。然而,本文将展示一种更巧妙、更有效的解法,让我们跳出动态规划的思维定势,探索算法的另一种可能性。

动态规划解法的基本思路是,记录每一步的路径数量,然后逐步累加求和。具体而言,对于网格中的每个单元格 (i, j),其可达到的路径数 dp[i][j] 等于它上方单元格 (i-1, j) 的路径数加上它左方单元格 (i, j-1) 的路径数,即:

dp[i][j] = dp[i-1][j] + dp[i][j-1]

使用这种自底向上的方法,我们可以从左上角的单元格开始,逐行逐列地计算出每个单元格的路径数。最终,右下角单元格的路径数就是我们要求的结果。

然而,对于这道题,我们可以采用一种更直接、更巧妙的组合数学解法。关键 insight 是,从左上角到右下角的路径实际上是由向右移动和向下移动组成的。在 m×n 的网格中,我们需要向右移动 (n-1) 次,向下移动 (m-1) 次。

因此,我们可以将这个问题抽象为一个组合问题:从 m+n-2 个移动中选择 m-1 个向下移动。这可以用组合公式表示为:

C(m+n-2, m-1)

这个组合公式的含义是,从 m+n-2 个元素中选择 m-1 个元素的方案数。通过计算这个组合数,我们就可以得到从左上角到右下角的不同路径数。

为了证明这个组合公式的正确性,我们可以使用数学归纳法。

基例: 当 m=1 或 n=1 时,网格只有一行或一列,只有一条路径。此时,组合公式 C(m+n-2, m-1) = C(n-1, 0) = 1,与实际路径数相等。

归纳步骤: 假设当网格为 k×l 时,组合公式 C(k+l-2, k-1) 给出了正确的路径数。现在考虑一个 k+1×l+1 的网格。从左上角到右下角的路径要么经过底部的第 k+1 行,要么经过右边的第 l+1 列。

  • 经过底部的第 k+1 行: 在这种情况下,路径可以表示为一个从 k×l 网格中到右下角的路径,后跟一个向右移动。根据归纳假设,有 C(k+l-2, k-1) 条这样的路径。
  • 经过右边的第 l+1 列: 在这种情况下,路径可以表示为一个从 k×l 网格中到右下角的路径,后跟一个向下移动。根据归纳假设,有 C(k+l-2, k-1) 条这样的路径。

因此,对于 k+1×l+1 的网格,从左上角到右下角的不同路径数是:

C(k+l-2, k-1) + C(k+l-2, k-1) = 2 * C(k+l-2, k-1) = C(k+l, k)

这正是当 m=k+1、n=l+1 时组合公式 C(m+n-2, m-1) 的值。

因此,通过数学归纳法,我们证明了组合公式 C(m+n-2, m-1) 给出了 m×n 网格中从左上角到右下角的不同路径数。

考虑一个 3×4 的网格。使用动态规划解法,我们可以逐行逐列地计算出每个单元格的路径数:

dp[1][1] = 1
dp[1][2] = 1
dp[1][3] = 2
dp[1][4] = 3
dp[2][1] = 1
dp[2][2] = 2
dp[2][3] = 3
dp[2][4] = 4
dp[3][1] = 2
dp[3][2] = 3
dp[3][3] = 4
dp[3][4] = 5

右下角单元格的路径数为 5,与组合公式 C(3+4-2, 3-1) = C(5, 2) = 10 计算的结果相同。

虽然动态规划是一种强大的算法,但它并非解决所有问题的唯一方法。对于 LeetCode 62 题,组合数学解法提供了更直接、更巧妙的解决方案。通过理解问题的本质并应用适当的数学知识,我们可以跳出固有的思维定势,探索算法设计中更多的可能性。

LeetCode 62 题,Unique Paths,是一道经典的动态规划问题。本文介绍了一种更优解法,它使用组合数学来计算从左上角到右下角的不同路径数。这种解法避免了动态规划的复杂性,提供了更直接、更巧妙的解决方案。文章深入分析了组合数学解法的原理,并用示例说明了它的正确性。对于希望深入理解算法设计和组合数学应用的读者来说,本文提供了有价值的见解。