Decode Ways II LeetCode Solution

Last updated on March 1st, 2025 at 08:56 pm

Here, we see a Decode Ways II LeetCode Solution. This Leetcode problem is solved using different approaches in many programming languages, such as C++, Java, JavaScript, Python, etc.

List of all LeetCode Solution

Topics

Dynamic Programming

Companies

Facebook

Level of Question

Hard

Decode Ways II LeetCode Solution

Decode Ways II LeetCode Solution

1. Problem Statement

A message containing letters from 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 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".

In addition to the mapping above, an encoded message may contain the '*' character, which can represent any digit from '1' to '9' ('0' is excluded). For example, the encoded message "1*" may represent any of the encoded messages "11""12""13""14""15""16""17""18", or "19". Decoding "1*" is equivalent to decoding any of the encoded messages it can represent.

Given a string s consisting of digits and '*' characters, return the number of ways to decode it.

Since the answer may be very large, return it modulo 109 + 7.

Example 1:
Input: s = “*”
Output: 9
Explanation: The encoded message can represent any of the encoded messages “1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, or “9”. Each of these can be decoded to the strings “A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, and “I” respectively.
Hence, there are a total of 9 ways to decode “*”.

Example 2:
Input: s = “1*”
Output: 18
Explanation: The encoded message can represent any of the encoded messages “11”, “12”, “13”, “14”, “15”, “16”, “17”, “18”, or “19”. Each of these encoded messages have 2 ways to be decoded (e.g. “11” can be decoded to “AA” or “K”).
Hence, there are a total of 9 * 2 = 18 ways to decode “1*”.

Example 3:
Input: s = “2*”
Output: 15
Explanation: The encoded message can represent any of the encoded messages “21”, “22”, “23”, “24”, “25”, “26”, “27”, “28”, or “29”. “21”, “22”, “23”, “24”, “25”, and “26” have 2 ways of being decoded, but “27”, “28”, and “29” only have 1 way.
Hence, there are a total of (6 * 2) + (3 * 1) = 12 + 3 = 15 ways to decode “2*”.

2. Coding Pattern Used in Solution

The coding pattern used in all the provided implementations is Dynamic Programming (DP). Specifically, this problem is a variation of the Fibonacci Numbers pattern, where the solution to the current state depends on the solutions to one or two previous states. The problem involves decoding a string with constraints, and the DP approach is used to calculate the number of valid decodings efficiently.

3. Code Implementation in Different Languages

3.1 Decode Ways II C++

class Solution {
public:
    int MOD = 1e9+7;
    int dp[100001];
    int helper(int ind, string &s){
        if(ind == s.size()){
            return 1;
        }
        if(s[ind] == '0'){
            return 0;
        }
        if(dp[ind] != -1){
            return dp[ind];
        }
        long long first = helper(ind+1, s);
        if(s[ind] == '*'){
            first = (first*9)%MOD;
        }
        long long second = 0;
        long long third = 0;
        if(ind+1 < s.size()){
            if(s[ind] == '1' || s[ind] == '*'){
                if(s[ind+1] == '*'){
                    second = helper(ind+2, s);
                    second = (second*9)%MOD;
                }
                else if(s[ind+1] != '*'){
                    second = helper(ind+2, s);
                }
            }
            if(s[ind] == '2' || s[ind] == '*'){
                if(s[ind+1] == '*') {
                    third = helper(ind+2, s);
                    third = (third*6)%MOD;
                }
                else if(s[ind+1]-'0' <= 6){
                    third = helper(ind+2, s);
                }
            }
        }
        return dp[ind] = ((first+second)%MOD+third)%MOD;
    }
    int numDecodings(string s) {
        memset(dp, -1, sizeof(dp));
        return helper(0, s);
    }
};

3.2 Decode Ways II Java

class Solution {
    public int numDecodings(String s) {
        if (s == null) {
            throw new IllegalArgumentException("Input string is null");
        }
        if (s.length() == 0 || s.charAt(0) == '0') {
            return 0;
        }
        long pre = 1; // dp[i-2]
        long cur = s.charAt(0) == '*' ? 9 : 1;
        for (int i = 1; i < s.length(); i++) {
            long sum = 0; // dp[i]
            char curChar = s.charAt(i);
            char preChar = s.charAt(i - 1);
            if (curChar != '0') {
                sum = cur * (curChar == '*' ? 9 : 1);
            }
            if (preChar == '*') {
                if (curChar == '*') {
                    sum += pre * 15;
                } else if (curChar <= '6') {
                    sum += pre * 2;
                } else {
                    sum += pre;
                }
            } else {
                if (curChar == '*') {
                    if (preChar == '1') {
                        sum += pre * 9;
                    } else if (preChar == '2') {
                        sum += pre * 6;
                    }
                } else {
                    int num = Integer.parseInt(s.substring(i - 1, i + 1));
                    if (num >= 10 && num <= 26) {
                        sum += pre;
                    }
                }
            }
            pre = cur;
            cur = sum % 1000000007;
        }
        return (int) cur;
    }
}

3.3 Decode Ways II JavaScript

var numDecodings = function(s) {
    let mod = 1e9 + 7;
    let [e0, e1, e2, f0] = [1, 0, 0, 0];
    for (const c of s) {
        if (c == '*') {
            f0 = 9 * e0 + 9 * e1 + 6 * e2;
            e1 = e0;
            e2 = e0;
        } else {
            f0 = (c > '0') * e0 + e1 + (c <= '6') * e2;
            e1 = (c == '1') * e0;
            e2 = (c == '2') * e0;
        }
        e0 = f0 % mod;
    }
    return e0;  
};

3.4 Decode Ways II Python

class Solution(object):
    def numDecodings(self, S):
        answer = 1
        prev_answer = 1
        one, two = False, False
        for i in S:
            if i == '*':
                new = answer*9
                if one:
                    new += 9*prev_answer
                if two:
                    new += 6*prev_answer
                one, two = True, True
            else:
                new = answer if (i > '0') else 0
                if one:
                    new += prev_answer
                if (two and i <= '6'):
                    new += prev_answer
                one = (i == '1')
                two = (i == '2')
            prev_answer = answer
            answer = new % (10**9 + 7)
        return answer

4. Time and Space Complexity

Time ComplexitySpace Complexity
C++O(n)O(n)
JavaO(n)O(1)
JavaScriptO(n)O(1)
PythonO(n)O(1)
  • The problem is solved using the Dynamic Programming pattern, specifically a variation of the Fibonacci Numbers pattern.
  • The C++ implementation uses recursion with memoization, leading to higher space usage compared to the iterative approaches in Java, JavaScript, and Python.
  • The iterative approaches (Java, JavaScript, Python) are more space-efficient, with O(1) space complexity.
  • All implementations have a time complexity of O(n), as they process each character of the string exactly once.
Scroll to Top