91. Decode Ways
Decode Ways
A message containing letters A-Z
can be encoded into numbers using the following mapping:
'A' -> "1" 'B' -> "2" ... 'Z' -> "26"
To decode an encoded message, all the digits must be grouped and then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, "11106"
can be mapped into:
"AAJF"
with the grouping(1 1 10 6)
"KJF"
with the grouping(11 10 6)
Note that the grouping (1 11 06)
is invalid because "06"
cannot be mapped into 'F'
since "6"
is different from "06"
.
Given a string s
containing 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.
Example 1:
Input: s = "12" Output: 2 Explanation: "12" could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: s = "226" Output: 3 Explanation: "226" could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
Example 3:
Input: s = "06"
Output: 0
Explanation: "06" cannot be mapped to "F" because of the leading zero ("6" is different from "06").
Constraints:
1 <= s.length <= 100
s
contains only digits and may contain leading zero(s).
Approach) Dynamic Programming
- i = 0; 1 (the first character '2' has 1 decoding method)
- i = 1; 2 (the first two characters '22' have 2 decoding methods)
- i = 2; 3 (the first three characters '222' have 3 decoding methods)
- i = 3; 5 (the first four characters '2223' have 5 decoding methods)
/**
* @param {string} s
* @return {number}
*/
const numDecodings = (s) => {
if (s[0] === '0') return 0
const ways = new Array(s.length+1).fill(0).fill(1, 0, 2) // [1,1,0,0,.....]
for (let i = 2; i <= s.length; i++) {
let prevOne = Number(s[i-1]) // first character
let prevTwo = Number(s[i-2])*10 + Number(s[i-1]) // first two characters
if (1 <= prevOne && prevOne <= 9) ways[i] += ways[i-1]
if (10 <= prevTwo && prevTwo <= 26) ways[i] += ways[i-2]
}
return ways[s.length]
}
Runtime: 80 ms, faster than 81.65% of JavaScript online submissions for Decode Ways.
Memory Usage: 42.2 MB, less than 82.90% of JavaScript online submissions for Decode Ways.
Complexity
Time ComplexityTime complexity will be O(n).
Space Complexity
space complexity should also be O(n).
Top Down
const numDecodings = (s, cur = 0, dp = {}) => {
if (dp[cur]) return dp[cur]; // Already processed so return
if (s[cur] === '0') return 0; // Not valid, return 0
if (cur >= s.length - 1) return 1; // Terminating case
return (dp[cur] =
numDecodings(s, cur + 1, dp) + // We process one char (that is not 0)
(s[cur] + s[cur + 1] <= 26 ? numDecodings(s, cur + 2, dp) : 0)); // If it's a valid num <= 26, we process two chars
};
Bottom Up
const numDecodings = (s) => {
const dp = Array(s.length + 1).fill(0);
dp[0] = 1;
for (let i = 1; i <= s.length; i++) {
const one = Number(s.slice(i - 1, i)); // '0' to '9'
const two = Number(s.slice(i - 2, i)); // '00' to '99'
if (one !== 0) dp[i] += dp[i - 1]; // We want [1, 9]
if (10 <= two && two <= 26) dp[i] += dp[i - 2]; // We want [10, 26]
}
return dp[s.length];
};
Approach) Recursive caching solution (DFS)
const numDecodings = (s) => {
const dp = { // cache i:
[s.length]: 1
}
const dfs = (i) => { // i is the position we are at in s
if (i in dp) { // if i has already been cached or if it's the last position in our string
return dp[i];
}
if (s[i] === '0') { // bad base case: if char is starting with 0 then it is invalid
return 0;
}
let result = dfs(i + 1); // we take the char at i as a single digit
if ( // if double-digit value between 10-26
i + 1 < s.length && // if we do have a second char that comes after the first
(
s[i] === '1' || // if double-digit value starts with 1 and there is a second digit then we have a valid double-digit value that starts with 1 ex: 10 - 19
( // if double-digit value starts with 2 and there is a second digit from 0 - 6, then we have a valid double-digit value that is in the range of 20-26
s[i] === '2' &&
'0123456'.search(s[i + 1]) !== -1
)
)
) {
result += dfs(i + 2); // add dfs of valid double-digit value to current result
}
dp[i] = result; // cache result
return result;
}
return dfs(0); // returns result of how many ways can decode string starting at index 0
}
Conclusion
That’s all folks! In this post, we solved LeetCode problem #91. Decode Ways
I hope you have enjoyed this post. Feel free to share your thoughts on this.
You can find the complete source code on my GitHub repository. If you like what you learn. feel free to fork 🔪 and star ⭐ it.
In this blog, I have tried to solve leetcode questions & present the most important points to consider when improving Data structure and logic, feel free to add, edit, comment, or ask. For more information please reach me here
Happy coding!
Comments
Post a Comment