Decode Ways
Decode Ways is a medium dynamic programming problem solved with the 1d dp pattern.
The best approach, optimal (two variables), runs in O(n) time and O(1) space.
Below are 3 approaches in Java, from recursion up.
Problem
A message of letters was encoded as digits with A = 1, B = 2, ..., Z = 26. Given the digit string, return the number of ways to decode it.
Examples
Example 1
- Input
s = "226"- Output
3- Why
- 2 2 6, 22 6, 2 26.
Example 2
- Input
s = "06"- Output
0- Why
- A code cannot start with 0.
Constraints
1 <= s.length <= 100; digits only.- A = 1, ..., Z = 26.
Animated walkthrough
A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.
Concepts first, then the problem and every approach, step by step.
Space to play or pause · ← → to jump a step · click or drag the bar to seek
Solutions
Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.
| Approach | Time | Space |
|---|---|---|
| Recursion | O(2ⁿ) | O(n) |
| Tabulation | O(n) | O(n) |
| Optimal (two variables) | O(n) | O(1) |
1Recursion
O(2ⁿ)O(n)From position i, take one digit (if not 0) or two digits (if 10–26) and recurse.
- If i == n return 1; if s[i] == '0' return 0.
- ways(i + 1) + (valid pair ? ways(i + 2) : 0).
class Solution {
public int numDecodings(String s) {
return ways(s, 0);
}
private int ways(String s, int i) {
if (i == s.length()) return 1;
if (s.charAt(i) == '0') return 0;
int r = ways(s, i + 1);
if (i + 1 < s.length() && Integer.parseInt(s.substring(i, i + 2)) <= 26) r += ways(s, i + 2);
return r;
}
}2Tabulation
O(n)O(n)dp[0] = 1 (empty prefix). For each i, add dp[i - 1] when the last digit alone is valid, and dp[i - 2] when the last two digits form 10–26.
- one = s[i - 1]; two = s[i - 2..i - 1] as a number.
- if one != '0': dp[i] += dp[i - 1]; if 10 <= two <= 26: dp[i] += dp[i - 2].
class Solution {
public int numDecodings(String s) {
int n = s.length();
int[] dp = new int[n + 1];
dp[0] = 1;
for (int i = 1; i <= n; i++) {
if (s.charAt(i - 1) != '0') dp[i] += dp[i - 1];
if (i >= 2) {
int two = (s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0');
if (two >= 10 && two <= 26) dp[i] += dp[i - 2];
}
}
return dp[n];
}
}3Optimal (two variables)
O(n)O(1)dp[i] needs only dp[i - 1] and dp[i - 2].
- prev2 = 1 (dp[0]), prev1 = dp[1]; roll forward.
class Solution {
public int numDecodings(String s) {
int prev2 = 1, prev1 = s.charAt(0) == '0' ? 0 : 1;
for (int i = 2; i <= s.length(); i++) {
int cur = 0;
if (s.charAt(i - 1) != '0') cur += prev1;
int two = (s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0');
if (two >= 10 && two <= 26) cur += prev2;
prev2 = prev1;
prev1 = cur;
}
return prev1;
}
}Edge cases to test
- Leading zero
- Zeros that must pair with the previous digit (10, 20)
- Invalid pairs such as 30
Hints
Hint 1
dp[i] = ways to decode the first i characters. Add dp[i - 1] if s[i - 1] is 1–9, and dp[i - 2] if s[i - 2..i - 1] is 10–26.
FAQ
What is the best time complexity for Decode Ways?
Optimal (two variables) runs in O(n) time and O(1) extra space.
Which pattern does Decode Ways use?
It is a dynamic programming problem that uses the 1d dp pattern. Other problems with the same pattern: Fibonacci Number, Climbing Stairs, Min Cost Climbing Stairs (2 jumps).
Is there a brute force solution for Decode Ways?
Yes. Recursion takes O(2ⁿ) time and O(n) space. From position i, take one digit (if not 0) or two digits (if 10–26) and recurse.
Which edge cases should I test for Decode Ways?
Leading zero; Zeros that must pair with the previous digit (10, 20); Invalid pairs such as 30.