Decode Ways medium
Problem Statement
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.
The test cases are generated so that the answer fits in the range [1, 105].
Example 1:
Input: s = "12" Output: 2 Explanation: It could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: s = "226" Output: 3 Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
Steps to Solve
The problem can be solved using dynamic programming. We can build a DP table where dp[i]
represents the number of ways to decode the string up to index i
.
-
Base Cases:
dp[0] = 1
(Empty string has one way to decode - itself)dp[1] = 1
if s[0] is a valid character (1-9), otherwise 0.
-
Iteration: For each index
i
(starting from 2), we consider two possibilities:- Decode the current character alone: If
s[i-1]
is a digit from 1 to 9, thendp[i] += dp[i-1]
. - Decode the last two characters together: If
s[i-2:i]
(substring of length 2) represents a number from 10 to 26, thendp[i] += dp[i-2]
.
- Decode the current character alone: If
-
Result:
dp[n]
(where n is the length of the string) will hold the total number of ways to decode the entire string.
Explanation
The dynamic programming approach avoids redundant calculations. By storing the number of ways to decode substrings, we can efficiently compute the result for the entire string. The base cases handle the trivial scenarios of empty or single-character strings. The iterative step carefully checks the validity of single and two-character decodings to ensure accuracy.
Code
#include <string>
#include <vector>
using namespace std;
int numDecodings(string s) {
int n = s.length();
if (n == 0) return 0; // Handle empty string case
vector<int> dp(n + 1, 0);
dp[0] = 1; // Base case: empty string has one decoding
if (s[0] != '0') { //Base case: Single digit
dp[1] = 1;
}
for (int i = 2; i <= n; i++) {
int oneDigit = s[i - 1] - '0';
int twoDigits = (s[i - 2] - '0') * 10 + (s[i - 1] - '0');
if (oneDigit >= 1 && oneDigit <= 9) {
dp[i] += dp[i - 1];
}
if (twoDigits >= 10 && twoDigits <= 26) {
dp[i] += dp[i - 2];
}
}
return dp[n];
}
Complexity Analysis
- Time Complexity: O(n), where n is the length of the string. We iterate through the string once.
- Space Complexity: O(n), due to the
dp
vector used for dynamic programming. This can be optimized to O(1) by only storing the last two DP values.