返回介绍

solution / 0600-0699 / 0639.Decode Ways II / README_EN

发布于 2024-06-17 01:03:36 字数 7504 浏览 0 评论 0 收藏 0

639. Decode Ways II

中文文档

Description

A message containing letters from A-Z can be encoded into numbers using the following mapping:

'A' -> "1"
'B' -> "2"
...
'Z' -> "26"

To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, "11106" can be mapped into:

  • "AAJF" with the grouping (1 1 10 6)
  • "KJF" with the grouping (11 10 6)

Note that the grouping (1 11 06) is invalid because "06" cannot be mapped into 'F' since "6" is different from "06".

In addition to the mapping above, an encoded message may contain the '*' character, which can represent any digit from '1' to '9' ('0' is excluded). For example, the encoded message "1*" may represent any of the encoded messages "11", "12", "13", "14", "15", "16", "17", "18", or "19". Decoding "1*" is equivalent to decoding any of the encoded messages it can represent.

Given a string s consisting of digits and '*' characters, return _the number of ways to decode it_.

Since the answer may be very large, return it modulo 109 + 7.

 

Example 1:

Input: s = "*"
Output: 9
Explanation: The encoded message can represent any of the encoded messages "1", "2", "3", "4", "5", "6", "7", "8", or "9".
Each of these can be decoded to the strings "A", "B", "C", "D", "E", "F", "G", "H", and "I" respectively.
Hence, there are a total of 9 ways to decode "*".

Example 2:

Input: s = "1*"
Output: 18
Explanation: The encoded message can represent any of the encoded messages "11", "12", "13", "14", "15", "16", "17", "18", or "19".
Each of these encoded messages have 2 ways to be decoded (e.g. "11" can be decoded to "AA" or "K").
Hence, there are a total of 9 * 2 = 18 ways to decode "1*".

Example 3:

Input: s = "2*"
Output: 15
Explanation: The encoded message can represent any of the encoded messages "21", "22", "23", "24", "25", "26", "27", "28", or "29".
"21", "22", "23", "24", "25", and "26" have 2 ways of being decoded, but "27", "28", and "29" only have 1 way.
Hence, there are a total of (6 * 2) + (3 * 1) = 12 + 3 = 15 ways to decode "2*".

 

Constraints:

  • 1 <= s.length <= 105
  • s[i] is a digit or '*'.

Solutions

Solution 1

class Solution:
  def numDecodings(self, s: str) -> int:
    mod = int(1e9 + 7)
    n = len(s)

    # dp[i - 2], dp[i - 1], dp[i]
    a, b, c = 0, 1, 0
    for i in range(1, n + 1):
      # 1 digit
      if s[i - 1] == "*":
        c = 9 * b % mod
      elif s[i - 1] != "0":
        c = b
      else:
        c = 0

      # 2 digits
      if i > 1:
        if s[i - 2] == "*" and s[i - 1] == "*":
          c = (c + 15 * a) % mod
        elif s[i - 2] == "*":
          if s[i - 1] > "6":
            c = (c + a) % mod
          else:
            c = (c + 2 * a) % mod
        elif s[i - 1] == "*":
          if s[i - 2] == "1":
            c = (c + 9 * a) % mod
          elif s[i - 2] == "2":
            c = (c + 6 * a) % mod
        elif (
          s[i - 2] != "0"
          and (ord(s[i - 2]) - ord("0")) * 10 + ord(s[i - 1]) - ord("0") <= 26
        ):
          c = (c + a) % mod

      a, b = b, c

    return c
class Solution {

  private static final int MOD = 1000000007;

  public int numDecodings(String s) {
    int n = s.length();
    char[] cs = s.toCharArray();

    // dp[i - 2], dp[i - 1], dp[i]
    long a = 0, b = 1, c = 0;
    for (int i = 1; i <= n; i++) {
      // 1 digit
      if (cs[i - 1] == '*') {
        c = 9 * b % MOD;
      } else if (cs[i - 1] != '0') {
        c = b;
      } else {
        c = 0;
      }

      // 2 digits
      if (i > 1) {
        if (cs[i - 2] == '*' && cs[i - 1] == '*') {
          c = (c + 15 * a) % MOD;
        } else if (cs[i - 2] == '*') {
          if (cs[i - 1] > '6') {
            c = (c + a) % MOD;
          } else {
            c = (c + 2 * a) % MOD;
          }
        } else if (cs[i - 1] == '*') {
          if (cs[i - 2] == '1') {
            c = (c + 9 * a) % MOD;
          } else if (cs[i - 2] == '2') {
            c = (c + 6 * a) % MOD;
          }
        } else if (cs[i - 2] != '0' && (cs[i - 2] - '0') * 10 + cs[i - 1] - '0' <= 26) {
          c = (c + a) % MOD;
        }
      }

      a = b;
      b = c;
    }

    return (int) c;
  }
}
const mod int = 1e9 + 7

func numDecodings(s string) int {
  n := len(s)

  // dp[i - 2], dp[i - 1], dp[i]
  a, b, c := 0, 1, 0
  for i := 1; i <= n; i++ {
    // 1 digit
    if s[i-1] == '*' {
      c = 9 * b % mod
    } else if s[i-1] != '0' {
      c = b
    } else {
      c = 0
    }

    // 2 digits
    if i > 1 {
      if s[i-2] == '*' && s[i-1] == '*' {
        c = (c + 15*a) % mod
      } else if s[i-2] == '*' {
        if s[i-1] > '6' {
          c = (c + a) % mod
        } else {
          c = (c + 2*a) % mod
        }
      } else if s[i-1] == '*' {
        if s[i-2] == '1' {
          c = (c + 9*a) % mod
        } else if s[i-2] == '2' {
          c = (c + 6*a) % mod
        }
      } else if s[i-2] != '0' && (s[i-2]-'0')*10+s[i-1]-'0' <= 26 {
        c = (c + a) % mod
      }
    }

    a, b = b, c
  }
  return c
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文