返回

前端实战:详解 LeetCode 91 题,JS 解码方法的动态规划解决方案

前端

导言

在日常生活中,加密和解密无处不在。例如,密码存储、信息传输和数据保护等场景都需要使用加密技术。在 LeetCode 91 题“解码方法”中,我们面临着一个编码和解码的挑战,需要利用动态规划算法来解决。

问题

给定一个仅包含数字 2-9 的字符串,每个数字对应一个字母(例如,2 对应 A,3 对应 B,...,9 对应 I)。求解码字符串有多少种不同的方法。

动态规划

动态规划是一种自顶向下的算法范式,适用于求解最优化问题。它将问题分解成较小的子问题,然后逐步解决子问题,最后合并子问题的解得到原问题的最优解。

算法原理

对于字符串中的每个字符,有两种解码方式:

  1. 将其作为一个独立的数字解码,得到一个字母。
  2. 将其与前一个字符一起解码,得到一个两位数的字母。

我们定义状态 dp[i] 为字符串前 i 个字符解码的方法数。则有以下递推关系:

dp[i] = dp[i-1] + (前一个字符和当前字符能组成两位数字母) ? dp[i-2] : 0

代码实现

function numDecodings(s) {
  if (!s || s.length === 0) return 0;
  if (s[0] === '0') return 0; // 第一个字符不能为 0

  const dp = new Array(s.length + 1).fill(0);
  dp[0] = 1;
  dp[1] = 1;

  for (let i = 2; i <= s.length; i++) {
    const prevChar = s[i - 2];
    const curChar = s[i - 1];
    if (curChar > '0') {
      dp[i] += dp[i - 1];
    }
    if (prevChar === '1' || (prevChar === '2' && curChar <= '6')) {
      dp[i] += dp[i - 2];
    }
  }

  return dp[s.length];
}

时间复杂度

动态规划算法的时间复杂度为 O(n),其中 n 为字符串的长度。这是因为我们遍历了字符串中的每个字符,并且每个字符的计算复杂度为常数。

总结

LeetCode 91 题“解码方法”是一个经典的算法问题,使用动态规划算法可以有效地求解。本文详细介绍了问题的背景、算法原理、代码实现和时间复杂度分析,帮助读者全面理解和掌握这道算法题。