Decode Ways
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ s.length ≤ 100 - ◆
s consists of digits only ('0'-'9')
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursive Without Memoization
BruteA digit string maps to letters A-Z (1-26) by grouping consecutive digits either one at a time or two at a time, and a '0' can only ever appear as the second digit of a valid two-digit group (since there's no letter for 0). Starting from the front of the string, the number of ways to decode the rest is the number of ways starting one digit later (treating the current digit alone) plus, when the next two digits together form a valid letter (10-26), the number of ways starting two digits later. Reaching the end of the string cleanly counts as exactly one valid decoding, and hitting a lone '0' that can't be grouped kills that entire branch.
O(2^n)O(n)1class Solution {
2 private String s;
3
4 public int decodeWays(String s) {
5 this.s = s;
6 return solve(0);
7 }
8
9 private int solve(int i) {
10 int n = s.length();
11 if (i == n) return 1;
12 if (s.charAt(i) == '0') return 0;
13 int ways = solve(i + 1);
14 if (i + 1 < n) {
15 int twoDigit = (s.charAt(i) - '0') * 10 + (s.charAt(i + 1) - '0');
16 if (twoDigit <= 26) ways += solve(i + 2);
17 }
18 return ways;
19 }
20}Optimal — Bottom-Up 1D DP
OptimalInstead of recursing from the front, build up the number of ways to decode each prefix of the string from the empty prefix onward. dp[i] holds the number of ways to decode the first i characters; the empty prefix and the first character (when it isn't '0') each count as exactly one way to start. For every later position, the last single digit contributes dp[i-1] ways whenever it's non-zero on its own, and the last two digits together contribute dp[i-2] ways whenever they form a number from 10 to 26 — adding both contributions gives dp[i], and the final entry holds the answer for the whole string.
O(n)O(n)1class Solution {
2 public int decodeWays(String s) {
3 int n = s.length();
4 if (n == 0 || s.charAt(0) == '0') return 0;
5 int[] dp = new int[n + 1];
6 dp[0] = 1;
7 dp[1] = 1;
8 for (int i = 2; i <= n; i++) {
9 int oneDigit = s.charAt(i - 1) - '0';
10 int twoDigit = (s.charAt(i - 2) - '0') * 10 + oneDigit;
11 if (oneDigit >= 1) dp[i] += dp[i - 1];
12 if (twoDigit >= 10 && twoDigit <= 26) dp[i] += dp[i - 2];
13 }
14 return dp[n];
15 }
16}