0091. Decode Ways¶
Problem¶
| Leetcode | 91. Decode Ways |
| Difficulty | |
| Tags | String, Dynamic Programming |
A message containing letters from
A-Zcan be encoded into numbers using the following mapping:To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways).
Given a string
scontaining only digits, return the number of ways to decode it.The test cases are generated so that the answer fits in a 32-bit integer.
Examples¶
Input: s = "12"
Output: 2 ("AB" or "L")
Input: s = "226"
Output: 3 ("BZ", "VF", "BBF")
Input: s = "06"
Output: 0
Constraints¶
1 <= s.length <= 100scontains only digits and may contain leading zero(s).
Approach: Dynamic Programming (O(1) Space)¶
Recurrence¶
Let dp[i] = ways to decode s[:i]. - Base: dp[0] = 1 (empty string has 1 decoding). - Single-digit step: if s[i-1] != '0', dp[i] += dp[i-1]. - Two-digit step: if s[i-2..i-1] is 10..26, dp[i] += dp[i-2].
Use rolling variables prev2 = dp[i-2], prev1 = dp[i-1].
Complexity¶
- Time: O(n)
- Space: O(1)
Implementation¶
Go¶
func numDecodings(s string) int {
n := len(s)
if n == 0 || s[0] == '0' {
return 0
}
prev2, prev1 := 1, 1
for i := 2; i <= n; i++ {
cur := 0
if s[i-1] != '0' {
cur += prev1
}
two := (int(s[i-2]-'0'))*10 + int(s[i-1]-'0')
if two >= 10 && two <= 26 {
cur += prev2
}
prev2, prev1 = prev1, cur
}
return prev1
}
Java¶
class Solution {
public int numDecodings(String s) {
int n = s.length();
if (n == 0 || s.charAt(0) == '0') return 0;
int prev2 = 1, prev1 = 1;
for (int i = 2; i <= n; 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;
}
}
Python¶
class Solution:
def numDecodings(self, s: str) -> int:
n = len(s)
if n == 0 or s[0] == '0': return 0
prev2, prev1 = 1, 1
for i in range(2, n + 1):
cur = 0
if s[i - 1] != '0': cur += prev1
two = int(s[i - 2:i])
if 10 <= two <= 26: cur += prev2
prev2, prev1 = prev1, cur
return prev1
Edge Cases¶
- Empty: 0
- Leading zero: 0
- "0": 0
- "10", "20": 1 each
- "30": 0
- "27": 1 (only single-digit)
- "100": 0 (00 is invalid)
- Long string of "1"s: Fibonacci-like growth