Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
