Decode Ways in Python

Suppose we have a message containing letters from A to Z that is being encoded to numbers using the following mapping − 'A' ? 1, 'B' ? 2 ... 'Z' ? 26. Given a non-empty string containing only digits, we need to find in how many ways that string can be decoded.

For example, if the string is "12", it can be decoded as "AB" (1,2) or "L" (12), so there are two possible ways.

Algorithm Approach

We will solve this using dynamic programming with the following steps ?

  • Create a DP array where dp[i] represents the number of ways to decode the string up to index i
  • Initialize dp[0] = 1 if the first character is not '0'
  • For each position, consider single digit (1-9) and two-digit (10-26) decodings
  • Sum up all valid decoding ways

Implementation

class Solution:
    def numDecodings(self, s):
        n = len(s)
        dp = [0 for i in range(n)]
        
        # Base case: first character
        if s[0] != '0':
            dp[0] = 1
        
        for i in range(1, n):
            # Single digit decoding (1-9)
            x = int(s[i])
            if x >= 1 and x <= 9:
                dp[i] += dp[i-1]
            
            # Two digit decoding (10-26)
            y = int(s[i-1:i+1])
            if y >= 10 and y <= 26:
                if i-2 >= 0:
                    dp[i] += dp[i-2]
                else:
                    dp[i] += 1
        
        return dp[-1]

# Test the solution
solution = Solution()
print(solution.numDecodings("226"))
print(solution.numDecodings("12"))
print(solution.numDecodings("06"))
3
2
0

How It Works

Let's trace through the example "226" ?

  • Index 0: '2' can be decoded as 'B', so dp[0] = 1
  • Index 1: '2' can be single digit (B) or "22" is invalid (>26), so dp[1] = 1
  • Index 2: '6' can be single digit (F) from dp[1], and "26" can be decoded as 'Z', so dp[2] = 1 + 1 = 2

Wait, let me recalculate this correctly ?

def numDecodings_detailed(s):
    n = len(s)
    dp = [0] * n
    
    print(f"String: {s}")
    
    # Base case
    if s[0] != '0':
        dp[0] = 1
    print(f"dp[0] = {dp[0]} (character '{s[0]}')")
    
    for i in range(1, n):
        # Single digit
        x = int(s[i])
        if x >= 1 and x <= 9:
            dp[i] += dp[i-1]
            print(f"Single digit {x}: dp[{i}] += dp[{i-1}] = {dp[i]}")
        
        # Two digits
        y = int(s[i-1:i+1])
        if y >= 10 and y <= 26:
            if i-2 >= 0:
                dp[i] += dp[i-2]
            else:
                dp[i] += 1
            print(f"Two digits {y}: dp[{i}] now = {dp[i]}")
    
    print(f"Final DP array: {dp}")
    return dp[-1]

result = numDecodings_detailed("226")
print(f"Total ways: {result}")
String: 226
dp[0] = 1 (character '2')
Single digit 2: dp[1] += dp[0] = 1
Two digits 22: dp[1] now = 2
Single digit 6: dp[2] += dp[1] = 2
Two digits 26: dp[2] now = 3
Final DP array: [1, 2, 3]
Total ways: 3

Edge Cases

solution = Solution()

# String starting with 0
print("'06':", solution.numDecodings("06"))

# String with 0 in middle  
print("'102':", solution.numDecodings("102"))

# Valid single character
print("'1':", solution.numDecodings("1"))
'06': 0
'102': 1
'1': 1

Conclusion

The dynamic programming solution efficiently counts all possible ways to decode a numeric string. The key insight is considering both single-digit (1-9) and two-digit (10-26) valid decodings at each position.

Updated on: 2026-03-25T07:48:13+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements