intermediate9 min read·Updated October 6, 2026

Decode Ways Explained: Tracing 226, 06, and 10

Master the Decode Ways dynamic programming pattern. Trace string '226', '06', and '10' step-by-step with mental models, edge cases, and time complexity.

By Learnisim AI·Published October 6, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
  • short strings
Decoding Ways (1=A ... 26=Z) — DP & Decision Tree 1. Recursive Tree: s = "226" (3 ways) start: "226" take '2' (B) left: "26" take '22' (V) left: "6" "6" (BBF) empty (BZ) empty (VF) 2. Edge Cases & Illegal Prefixes (0 is sticky!) s = "06" Ways: 0 (No '0' letter) s = "10" Ways: 1 ("10"=J) s = "30" Ways: 0 (>26 & '0') DP Recurrence Rules at Index i: • Single digit s[i-1] != '0' ⇒ add dp[i-1] • Two digits s[i-2..i-1] in [10, 26] ⇒ add dp[i-2] Otherwise, invalid prefix contributes 0 ways to final count. 3. DP Table State Transition for s = "226" (dp[i] = ways to decode prefix of length i) i = 0 (empty "") dp[0] = 1 Base case (empty string) i = 1 (prefix "2") dp[1] = 1 s[0] = '2' != '0' (dp[0]) i = 2 (prefix "226" len 2) dp[2] = 2 dp[1] (single '2') + dp[0] (pair '22')
Ways to decode "226" and "06" and "10" overview diagram
Why

Why Counting Decodings Breaks Down Fast Without Structure

Phase 1: The Combinatorial Maze

Imagine you are handed a numerical cipher where 1 represents A all the way to 26 representing Z. Your task is to figure out how many valid English word-prefix combinations can be formed from a sequence of digits. Consider our working example: the string s = "226".
At first glance, you might think you can just eyeball the pieces. You could slice it into single digits: 2, 2, and 6, which map to B, B, and F. Or you could group the first two digits together: 22 and 6, mapping to V and F. Or maybe group the last two: 2 and 26, mapping to B and Z. That gives us 3 distinct ways to decode "226".
Simple enough for three digits, right? But what happens when we look at strings that contain zeros, like s = "06" or s = "10"? In "06", the leading zero ruins the first character because there is no letter corresponding to 0. In "10", the zero cannot stand alone either—it must combine with the preceding 1 to form 10 (J), meaning 1 and 0 cannot be split into 1 and 0 (A and nothing).
If you try to write a brute-force recursive function that branches at every single step—deciding whether to take one digit or two digits—you will quickly find yourself recalculating the exact same suffixes over and over again. For a string of length , naive branching leads to time complexity. Without a systematic way to track subproblem states, even a modest string will melt your call stack.
Why Counting Decodings Breaks Down Fast Without Structure Decoding Cipher (1=A ... 26=Z) | Analyzing "226", "06", and "10" String: "226" (3 Ways) Split 1: [2] [2] [6] B - B - F Split 2: [22] [6] V - F Split 3: [2] [26] B - Z Zero Traps & Rules String "06": Leading '0' is invalid Result: 0 ways (No letter maps to '0') String "10": '0' cannot stand alone Must combine: [10] = J (1 valid way) Naive Recursion vs. Memoization s Take 1 Digit Take 2 Digits O(2ⁿ) Time Recalculates exact suffixes repeatedly! The Structural Fix: DP Table dp[i] = dp[i+1] + dp[i+2] (valid checks) Builds solutions from right to left. O(N) Time
Why Counting Decodings Breaks Down Fast Without Structure diagram
Model

The Recursive Tree: Splitting Digits Into Singletons and Pairs

Phase 2: The Core Decoding Model

When we look at our working example , we are really asking: at each position in the string, do we consume a single digit like 2 (mapping to B), or do we pair it with the next digit like 22 (mapping to V)? This dual-choice structure turns string decoding into a step-by-step decision tree.
Imagine standing at the start of . Your first choice is either to take the single digit 2 and leave "26" to be decoded, or to take the double digit 22 and leave "6" to be decoded. If you take 2, you branch into all valid decodings of "26". If you take 22, you branch into all valid decodings of "6".
This overlapping substructure means that naive recursion will recompute the same suffixes over and over. To build a robust mental model, we map each index of the string to a subproblem: how many valid decodings exist for the prefix of length ?
Let us formalize the transition at index :
- Single-digit check: If the character at is not , it can be decoded on its own, contributing the decodings from .
- Double-digit check: If the two-character slice forms a valid number between 10 and 26 inclusive, it can be decoded as a pair, contributing the decodings from .
When we test this model on our second target , the first digit is , failing the single-digit check, and "06" is not a valid 10-26 pair, yielding 0 decodings immediately. For , the single digit is valid but cannot stand alone if followed by unless paired, whereas the pair "10" is valid (), giving us exactly 1 way.
Decoding Ways: Splitting Digits Into Singletons & Pairs ("226") Recursive tree decision model & edge cases ("06" & "10") Start: "226" Take '2' (B) Left: "26" Take '22' (V) Left: "6" '2' → "6" (F) '26' (Z) '6' (F) Path 1 (BBF) Path 2 (BZ) Path 3 (VF) Total Ways = 3 Core Transition Rules at Index i 1 Single-Digit Check (s[i-1] != '0') Contributes decodings from dp[i-1] 2 Double-Digit Check (10 <= pair <= 26) Contributes decodings from dp[i-2] dp[i] = (valid_single ? dp[i-1] : 0) + (valid_pair ? dp[i-2] : 0) Edge Case: s = "06" Single check: s[0] == '0' (Invalid) Cannot stand alone Pair check: "06" < 10 (Invalid) Leading zero not allowed in pair Result: 0 Ways Edge Case: s = "10" Single check: '1' valid, but '0' fails Must be paired with '0' Pair check: "10" is valid (J) Contributes dp[i-2] (1 way) Result: 1 Way (J) Why Overlapping Substructure? • Suffixes like "6" are reached multiple times. • Naive recursion recalculates identical states. • Dynamic Programming stores prefix decodings in O(n) time & space. Maps cleanly to Fibonacci sequence pattern!
The Recursive Tree: Splitting Digits Into Singletons and Pairs diagram
Worked example

Tracing the DP Table for String 226, 06, and 10

Phase 3: Worked example

Now we put the dynamic programming recurrence into motion using our locked examples: s = "226", s = "06", and s = "10". We will maintain a DP array where dp[i] represents the number of valid ways to decode the prefix of length i.

Given

- Target string 1: s = "226"
- Target string 2: s = "06"
- Target string 3: s = "10"

Steps

For s = "226" (length ):
- Base cases: dp[0] = 1 (empty string has 1 way), and for , dp[1] = 1 because s[0] = '2' is non-zero.
- Step (string prefix "22"):
- Single-digit check: s[1] = '2' is non-zero, so add dp[1] (1).
- Double-digit check: substring "22" is between 10 and 26, so add dp[0] (1).
- Result: dp[2] = 1 + 1 = 2 (decodings: 2|2 and 22).
- Step (string prefix "226"):
- Single-digit check: s[2] = '6' is non-zero, so add dp[2] (2).
- Double-digit check: substring "26" is between 10 and 26, so add dp[1] (1).
- Result: dp[3] = 2 + 1 = 3.
For s = "06":
- Base case: dp[0] = 1.
- Step (prefix "0"):
- Single-digit check: s[0] = '0' is zero, so do not add dp[0]. Double-digit check: has no previous character.
- Result: dp[1] = 0.
- Step (prefix "06"):
- dp[2] depends on dp[1] (which is 0) and valid double digits. Because the prefix starts with a zero, all paths fail immediately.
- Result: dp[2] = 0.
For s = "10":
- Base cases: dp[0] = 1, dp[1] = 1 ('1' is non-zero).
- Step (prefix "10"):
- Single-digit check: s[1] = '0' is zero, so we cannot add dp[1]. (A zero cannot stand alone as A-Z).
- Double-digit check: substring "10" is valid (), so we add dp[0] (1).
- Result: dp[2] = 0 + 1 = 1 (decoding: 10 only).

Result

- "226" ways (2|2|6, 22|6, 2|26).
- "06" ways.
- "10" way (10).
python
def numDecodings(s: str) -> int:
    if not s or s[0] == '0':
        return 0
    n = len(s)
    dp = [0] * (n + 1)
    dp[0] = 1
    dp[1] = 1
    
    for i in range(2, n + 1):
        # TODO: Implement single-digit and double-digit transitions here
        pass
    return dp[n]
Phase 3: Tracing DP Tables for "226", "06", and "10" s = "226" dp[0] 1 dp[1] 1 dp[2] 2 dp[3] 3 Result: 3 ways (2|2|6, 22|6, 2|26) s = "06" dp[0] 1 dp[1] 0 dp[2] 0 Result: 0 ways (starts with '0', fails immediately) s = "10" dp[0] 1 dp[1] 1 dp[2] 1 Result: 1 way ('10' valid double digit, '0' standalone invalid) DP State Transition Rule for loop: 1. Single-digit: if s[i-1] != '0' add dp[i-1] 2. Double-digit: if 10 <= s[i-2..i-1] <= 26 add dp[i-2] dp[i] = single_ways + double_ways
Tracing the DP Table for String 226, 06, and 10 diagram
Practice

Practice: Computing Decode Ways for Edge Cases Like 30

Phase 4: Practice

Now that we have traced s = "226", s = "06", and s = "10", let us apply the exact same recurrence logic to a new input string: s = "30".
Recall the two rules from our DP model:
- A single digit adds dp[i-1] decodings only if it is non-zero (1 to 9).
- A two-digit pair adds dp[i-2] decodings only if it forms a valid number between 10 and 26.
Using these rules, trace out the values of the DP array for s = "30" from left to right, starting with dp[0] = 1, dp[1] = 0 (since s[0] = '3'), and compute the final output.
python
s = "30"
# Compute dp table for s = "30"
# dp[0] = 1
# dp[1] = ?
# dp[2] = ?
Apply

Transfer: Applying the Single-Pass DP Pattern to Similar Partition Counting

Phase 5: Apply

Now that you have traced 226, 06, 10, and handled the dangerous trap of 30, you possess a reusable mental model for bounded sequence-partitioning. The core lesson from the Decode Ways problem is not just alphabet substitution; it is how local validation constraints (1..26) interact with sequential choices of length 1 or length 2. When you encounter a new string processing challenge where elements can be consumed individually or paired up subject to validity rules, you can directly lift this dynamic programming state machine.
Consider a modified scenario: suppose you are decoding a stream of digits where a single digit maps to a valid symbol only if it is odd, and a two-digit pair maps to a valid symbol only if it falls between 11 and 39. The state update rule remains identical in spirit:
$|
By keeping track of just the last two subproblem states ( and ), you compress an exponential branching recursion into an time and space scan. Whenever local constraints restrict lookaheads of width , look for a recurrence relation summing over sliding window histories.

FAQ

How many ways can the string '226' be decoded?
The string '226' can be decoded in 3 ways: 2|2|6 (B-B-F), 22|6 (V-F), and 2|26 (B-Z).
Why does the string '06' return 0 valid decodings?
Leading zeros are invalid because numbers mapping to letters range from 1 to 26. Since '06' starts with a 0 and cannot be paired with the previous digit (as it's at index 0), it yields 0 ways.
How do you handle the string '10' in Decode Ways?
'10' has exactly 1 valid decoding ('J'). The digit '0' cannot stand alone, so it must combine with '1' to form '10', preventing the split into 1|0.
What is the time and space complexity of the DP solution for Decode Ways?
The time complexity is O(n) because we iterate through the string of length n once. The space complexity can be optimized to O(1) by storing only the results of the previous two states.

Keep learning