Skip to main content
Medium Dynamic Programming High frequency

Decode Ways

Open on LeetCode

Approach Summary

dp[i] = ways to decode s[0..i). Single digit: valid if not "0". Two digits: valid if in 10-26 range.

Full Solution & Approach

A digit string maps to letters where 1-26 are valid codes, and a leading zero is never a valid single-digit code. Let dp[i] be the number of ways to decode s[0..i), with dp[0] = 1. The last character alone is a valid decoding only if it is not "0", contributing dp[i-1] ways. The last two characters are valid only if they form a number from 10 to 26, contributing dp[i-2] ways. So dp[i] = (valid single digit ? dp[i-1] : 0) + (valid two digits ? dp[i-2] : 0). Because the recurrence only reads the previous two values, collapse the array into two rolling variables. The trap most people hit is "0": a zero can never be decoded alone and can only appear in 10 or 20, so the answer naturally becomes 0 for impossible strings like "30".

One pass with constant work per character — O(n) time. Two rolling variables — O(1) space.

Solution Code

Solution

def num_decodings(s: str) -> int:
    if not s or s[0] == '0':
        return 0
    prev2, prev1 = 1, 1  # ways for empty prefix and first char
    for i in range(1, len(s)):
        cur = 0
        if s[i] != '0':
            cur += prev1
        if 10 <= int(s[i - 1:i + 1]) <= 26:
            cur += prev2
        prev2, prev1 = prev1, cur
    return prev1

Edge Cases to Watch

  • Leading zero — no valid decoding, return 0
  • A zero not preceded by 1 or 2 — return 0
  • Empty string — return 1 per convention
  • A single non-zero digit — return 1

How to Recognize This Pattern

  • Number of ways to decode digit string
  • Leading zero constraint

Complexity Analysis

Time Complexity

O(n)

Space Complexity

O(1)

Tags

String DP

This site is free. If these guides are helping your prep, consider buying me a coffee. ☕

Support →
Buy me a coffee