Compile Ready
Module 2 · 1D Dynamic Programming

Decode Ways

MediumProblem 6 of 30 10 min read ~25 min to solve LeetCode
Dynamic Programming1D DPStringCounting
Asked atAmazonGoogleMicrosoftMetaBloomberg

Problem Statement

A message containing digits is encoded by mapping A to 1, B to 2, and so on through Z to 26. Given a digit string s, return the number of ways to decode it. A group with a leading zero is invalid, and 0 can only appear as part of 10 or 20.

Input

A digit string s.

Output

An integer: the number of valid decodings of the entire string.

Constraints

  • 1 <= s.length <= 100
  • s contains only digits and may contain leading zeroes

Examples

Example 1

Input:
s = 12
Output: 2
Explanation: The valid decodings are 1 + 2 and 12.

Example 2

Input:
s = 226
Output: 3
Explanation: The valid decodings are 2 + 2 + 6, 22 + 6, and 2 + 26.

Example 3

Input:
s = 06
Output: 0
Explanation: A leading zero cannot be decoded alone, and 06 is not a valid two-digit code.

Learning Objectives

  • Define DP over prefix length rather than over the current character alone.
  • Add contributions only when the one-digit or two-digit choice is valid.
  • Handle zeroes correctly without special-case explosions.
  • Compress the prefix-count table to two rolling counts.

Intuition

Think of decoding as walking through the string. At position i, the final decoded letter could use just the last digit, or it could use the last two digits. Those are the only possibilities because codes are from 1 through 26.

The tricky part is validity. A single digit contributes only if it is 1 through 9. A two-digit group contributes only if it is between 10 and 26. When a choice is valid, it appends one letter to every decoding of the remaining prefix, so it adds the count from the matching earlier prefix.

Common mistakes

  • ×Treating **0** as a valid single-digit code.
  • ×Accepting two-digit groups like **06** or **30**.
  • ×Defining **dp[i]** as ending at index **i** and then mixing it with prefix-length indices.
  • ×Replacing addition with max; this problem counts all valid choices, not the best choice.
  • ×Forgetting that **dp[0] = 1** represents the empty prefix needed by valid two-digit decodings at the start.

State Definition

Let dp[i] be the number of ways to decode the prefix of length i, meaning s[0...i - 1]. The answer is dp[n].

State Transition

For prefix length i, consider the final one or two digits:

  • If s[i - 1] is between 1 and 9, add dp[i - 1].
  • If s[i - 2...i - 1] is between 10 and 26, add dp[i - 2].

So dp[i] is the sum of the valid contributions. Base cases are dp[0] = 1 for the empty prefix and dp[1] = 1 only if the first character is not 0, otherwise 0.

Solutions

Solution: Prefix DP with two rolling counts

Keep the number of decodings for the previous prefix length and the prefix length two positions back. Each new position adds one or both counts depending on valid one-digit and two-digit endings.

Step-by-step

  1. Initialise twoPositionsBack = 1 for the empty prefix.
  2. Initialise onePositionBack based on whether the first digit is nonzero.
  3. For each prefix length from 2 to n, start current at 0.
  4. Add onePositionBack if the last digit is valid alone, and add twoPositionsBack if the last two digits form a valid code.
  5. Roll the two counts forward and return the final previous-prefix count.
Time

O(n)

Space

O(1)

Each character is examined a constant number of times with two stored counts.

Java implementation

Loading…

Dry Run

Sample input

s = 226. Use prefix lengths, with dp[0] = 1 and dp[1] = 1 for the prefix 2.

iprefixsingle digit contributiontwo digit contributiondp[i]
2222 is valid, add 122 is valid, add 12
32266 is valid, add 226 is valid, add 13

The final prefix count is 3, representing 2 + 2 + 6, 22 + 6, and 2 + 26.

Complexity Analysis

Decode Ways is still a constant-window 1D DP, but the recurrence is conditional because zeroes and values above 26 are invalid.

Prefix DP with two rolling counts

Time

O(n)

Space

O(1)

Each character is examined a constant number of times with two stored counts.

Interview Tips

Say that dp[i] counts decodings of a prefix of length i. That avoids off-by-one confusion and makes the two contributions obvious. Spend extra time explaining zero: 0 is never valid alone, while 10 and 20 are valid two-digit codes.

Likely follow-ups

  • How would you return the actual decoded strings for small inputs?
  • What changes if the mapping extends beyond 26?
  • How would you handle wildcard characters that can represent any digit?
  • How would you validate the input early if non-digit characters were allowed?

Similar Problems

Key Takeaways

  • Prefix-length state makes string DP transitions cleaner than raw character indices.
  • Single-digit and two-digit endings contribute only when they are valid codes.
  • The empty prefix count **dp[0] = 1** is essential for two-digit decodings at the beginning.
  • Zero handling is the core edge case: **0** alone is invalid, but **10** and **20** are valid.
Reusable template: Conditional prefix-count DP: for each prefix length, add the counts from valid one-step and two-step predecessor prefixes, then roll the two counts forward.