動的計画法で数字だけの暗号を文字に戻す読み方を数える

A を 1、B を 2、…、Z を 26 と置き換えて区切りを消した数字の列が、何通りの文字の並びに読めるかを数えます。最後の 1 桁か 2 桁で場合を分け、前の 2 つの答えを足していく練習です。

海外で定番の問題リスト 4 本には入っていません

問題

英大文字を、A は 1、B は 2、…、Z は 26 と数に置き換え、区切りを消してつなげた暗号があります。数字だけの文字列 digits を受け取り、元の英大文字の並びとして読める読み方が何通りあるかを返す関数を書いてください。

  • 1 文字は、1 桁 (1 から 9) か 2 桁 (10 から 26) の数です
  • 0 で始まる区切り (0 だけ、05 など) は、どの文字にも当たりません
  • どう区切っても読めないときは 0 を返します
  • digits の長さは 1 以上 100 以下で、答えは 2^31 より小さくなるものとします

入力と出力の例

例 1

1-2-2-6 (ABBF)、12-2-6 (LBF)、1-22-6 (AVF)、1-2-26 (ABZ)、12-26 (LZ) の 5 通りです。

digits = "1226"
5

例 2

0 は 1 文字にならないので、20 と区切るしかありません。20-5 (TE) の 1 通りです。

digits = "205"
1

例 3

0 は前の 3 とつないでも 30 で、26 を超えます。読めないので 0 です。

digits = "301"
0

面接での聞かれ方

面接では、階段の上り方の数え方に「0 の扱い」という罠を足した形で出されます。

  • 「A を 1、Z を 26 とした暗号の数字列は、何通りに読めますか」
  • 書く前に「06 は 6 と読めますか?」「読めないときは何を返しますか?」と確かめられるかを見られます
  • 書き終えると「0 がたくさん入った例で確かめてください」と、端の場合を手でたどるよう求められます

正しい形は階段と同じですが、0 の扱いで落とす人がとても多い問題です。

ヒント

まだ開いていません

付箋は 4 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

アルゴリズムのチートシートの「動的計画法 (DP)」に、この型の要点を表とコードでまとめています。

動的計画法は、途中の答えを覚えておいて、同じ計算をやり直さない書き方です。漸化式で言い直せる問題が多いです。

main.py
def decode_count(digits: str) -> int:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(decode_count("1226"))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します