Decode Ways
Letters were turned into numbers with A = 1, B = 2, and so on up to Z = 26, then all the digits were run together. Given that string of digits, count how many different messages it could have been. For example "12" could be "AB" (1 then 2) or "L" (12), so the answer is 2. Read the digits left to right. At each digit you either take it on its own or pair it with the digit before it, and a pair only counts when it lands between 10 and 26 . A zero can never stand alone, so the count for a position is the count from one step back plus the count from two steps back, keeping only the options that are legal.
Constraints
- 1 ≤ s.length ≤ 100
- s contains only digits
- s may contain leading zeros, in which case the answer is 0
Example
s = "2263"3Explanation "2263" reads as "BBFC" (2 2 6 3), "VFC" (22 6 3) or "BZC" (2 26 3), so there are 3 ways.
In plain terms
- Decode
- Turn the digits back into letters. The same digits can often be read more than one way, which is why they need counting.
- Valid pair
- Two digits read as a single letter. It has to be 10 to 26: "07" is not valid because no letter is number 7 written with a leading zero, and "27" is past Z.
- Running count
- The number of ways to decode everything up to a point. Each new count is built from the two counts before it, so only those two need remembering.
Count the ways to read each prefix of the digits
Start with one way to decode nothing and one way to decode "2".
What happens in this step
s = "2263" position 0 = 1, position 1 = 1 The first digit is 2, not zero, so "2" reads as B and nothing else. The later positions have not been worked out yet.
Steps to visualize
- The row is the 5 cut positions of "2263", from 0 (before any digit) to 4 (after the last).
- Each cell holds the number of ways to decode the digits up to that position.
- Position 0 is 1: there is exactly one way to decode nothing.
- Position 1 is 1 as long as the first digit is not zero.
- A digit that is not zero can stand alone, adding the count from one position back.
- A pair of digits between 10 and 26 adds the count from two positions back.
- The last cell is the answer.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Start with one way to decode nothing and one way to decode "2".
What happens in this step
s = "2263" position 0 = 1, position 1 = 1 The first digit is 2, not zero, so "2" reads as B and nothing else. The later positions have not been worked out yet.
Solution
function numDecodings(s) {
if (s.length === 0 || s[0] === '0') {
return 0;
}
let twoBack = 1;
let oneBack = 1;
for (let i = 1; i < s.length; i += 1) {
let current = 0;
if (s[i] !== '0') {
current += oneBack;
}
const pair = Number(s.slice(i - 1, i + 1));
if (pair >= 10 && pair <= 26) {
current += twoBack;
}
twoBack = oneBack;
oneBack = current;
}
return oneBack;
}- Time
- O(n)
- Space
- O(1)
Test cases
| Input | Expected | Covers |
|---|---|---|
s = "2263" | 3 | example from the description |
s = "12" | 2 | smallest string with more than one reading |
s = "226" | 3 | overlapping pairs 22 and 26 |
s = "06" | 0 | a string that cannot be decoded at all |
s = "10" | 1 | a zero that only works as part of a pair |
s = "1111" | 5 | a longer string where the counts grow |