返回轨道
算法 · 2026-05-14 · 21 阅读

P88 解码方式

算法 21 阅读

信号摘要

难度:Medium · 时长:10:26 · leetcode 91 · lintcode 512

P88 解码方式

未对外公开播放权限
点击查看说明

描述

这个题目说的是,给你一个加密后的非空字符串,原字符串由大写 A 到 Z 组成,加密后的字符串由数字字符组成,加密方法是把大写 A 到 Z 映射成 1 到 26。你要计算出给你的加密字符串有多少种可能的解码方式。

比如说,给你的加密字符串是:"124"。这个数字字符串有 3 种解码方式:
  1. 第一种是 "124" 各解码成一个字符,得到 ABD
  2. 第二种是 "12" 和 "4" 各解码成一个字符,得到 LD
  3. 第三种是 "1" 和 "24" 各解码成一个字符,得到 AX

因此,你要返回的答案就是 3 种。

映射关系: A -> 1 B -> 2 ... Z -> 26

代码

public class AlgoCasts {

  private boolean isValidTwoDigit(char a, char b) {
    return (a == '1' && b <= '9') || (a == '2' && b <= '6');
  }

  private int decode(char[] c, int i) {
    if (i == c.length) return 1;
    if (i > c.length) return 0;
    int num = 0;
    if (c[i] != '0') num += decode(c, i+1);
    if (i+1 < c.length && isValidTwoDigit(c[i], c[i+1])) num += decode(c, i+2);
    return num;
  }

  public int numberOfDecodingsRecursive(String s) {
    return decode(s.toCharArray(), 0);
  }

  // Time: O(n), Space: O(n)
  public int numberOfDecodingsDP(String s) {
    int[] d = new int[s.length() + 1];
    d[0] = 1;
    d[1] = s.charAt(0) != '0' ? 1 : 0;
    for (int i = 2; i <= s.length(); ++i) {
      if (s.charAt(i-1) != '0') d[i] += d[i-1];
      if (isValidTwoDigit(s.charAt(i-2), s.charAt(i-1))) d[i] += d[i-2];
    }
    return d[s.length()];
  }

  // Time: O(n), Space: O(1)
  public int numberOfDecodingsDPO1(String s) {
    int first = 1;
    int second = s.charAt(0) != '0' ? 1 : 0;
    for (int i = 2; i <= s.length(); ++i) {
      int third = 0;
      if (s.charAt(i-1) != '0') third += second;
      if (isValidTwoDigit(s.charAt(i-2), s.charAt(i-1))) third += first;
      first = second;
      second = third;
    }
    return second;
  }

}

📡 通讯频道