The problem. Letters are encoded as numbers: A = 1, B = 2, …, Z = 26. Given a string of digits s, return the number of ways to decode it. A piece like 06 is not valid — no letter is encoded with a leading zero.
s = "12" -> 2 ("AB" from 1 2, "L" from 12)
s = "226" -> 3 ("BZ", "VF", "BBF")
s = "06" -> 0 (a leading zero can't be decoded)Let ways[i] be the number of decodings of the first i digits. The last letter of a decoding used either one digit — valid if s[i−1] isn't 0 — leaving ways[i−1] decodings for the rest, or two digits — valid if s[i−2..i−1] is between 10 and 26 — leaving ways[i−2]. Add the valid cases. ways[0] = 1: the empty string has one (empty) decoding. Zeros are the whole difficulty: 0 can only appear as part of 10 or 20.
function numDecodings(s) { const memo = new Map(); const count = (i) => { // decodings of s[i..] if (i === s.length) return 1; // nothing left: one way if (s[i] === "0") return 0; // no letter starts with 0 if (memo.has(i)) return memo.get(i); let total = count(i + 1); // one digit if (i + 1 < s.length && Number(s.slice(i, i + 2)) <= 26) total += count(i + 2); // two digits memo.set(i, total); return total; }; return count(0);}Time O(n), space O(n). This version reads the string forwards from i, so its table would fill right to left — either direction works.
Each prefix adds the one-digit and the two-digit ways to finish it.
function numDecodings(s) { const n = s.length; const ways = new Array(n + 1).fill(0); // ways[i]: decodings of the first i digits ways[0] = 1; // the empty prefix for (let i = 1; i <= n; i++) { if (s[i - 1] !== "0") ways[i] += ways[i - 1]; // last letter: one digit, 1-9 const two = i >= 2 ? Number(s.slice(i - 2, i)) : 0; if (two >= 10 && two <= 26) ways[i] += ways[i - 2]; // last letter: two digits, 10-26 } return ways[n];}Time O(n), space O(n) — or O(1) with two variables, exactly as in Climbing Stairs (which this is, with rules about which steps are allowed).
"06": 0."10", "2101": the 0 must join the digit before it."30", "100": 0 ways."1111111111" grows like Fibonacci.* stands for any digit 1–9: the same recurrence with counts per case, modulo 10⁹ + 7.