Possible combinations and convert into alphabet algorithm in JavaScript

In JavaScript, we can solve the alphabet decoding problem where each letter maps to a number (a=1, b=2, ..., z=26). Given an encoded message, we need to count how many different ways it can be decoded back into letters.

For example, the message '111' can be decoded as 'aaa' (1-1-1), 'ka' (11-1), or 'ak' (1-11), giving us 3 possible combinations.

Understanding the Problem

The challenge is that some digit sequences can be interpreted in multiple ways:

  • Single digits 1-9 can be decoded as letters a-i
  • Two-digit combinations 10-26 can be decoded as letters j-z
  • We need to count all valid combinations

Recursive Solution

Here's a recursive approach that explores all possible decoding paths:

const waysToProcess = (message, ways = 0) => {
    if (message.length) {
        // Try single digit decode
        ways = waysToProcess(message.slice(1, message.length), ways);
        
        const numCurr = parseInt(message[0]);
        const numNext = "undefined" === typeof message[1] ? null : 
                       parseInt(message[1]);
        
        // Try two-digit decode if valid (10-26)
        if (numCurr && numNext
            && numCurr < 3
            && (numCurr * 10 + numNext) < 27
            && (numCurr * 10 + numNext) >= 10
        ) {
            ways = waysToProcess(message.slice(2, message.length), ways);
        }
    } else {
        // Base case: successfully decoded entire message
        ways++;
    }
    return ways;
}

console.log(waysToProcess('111'));  // 3
console.log(waysToProcess('226'));  // 3
console.log(waysToProcess('06'));   // 0 (invalid: leading zero)
3
3
0

How It Works

The algorithm uses recursion to explore two possibilities at each step:

  1. Single digit: Take one digit (1-9) and decode as a-i
  2. Two digits: Take two digits (10-26) and decode as j-z

For message '111':

  • Path 1: 1-1-1 ? a-a-a
  • Path 2: 11-1 ? k-a
  • Path 3: 1-11 ? a-k

Optimized Dynamic Programming Solution

For better performance with longer messages, here's a dynamic programming approach:

const countDecodings = (s) => {
    if (!s || s[0] === '0') return 0;
    
    const dp = new Array(s.length + 1).fill(0);
    dp[0] = 1; // Empty string has one way
    dp[1] = s[0] !== '0' ? 1 : 0;
    
    for (let i = 2; i <= s.length; i++) {
        // Single digit
        if (s[i-1] !== '0') {
            dp[i] += dp[i-1];
        }
        
        // Two digits
        const twoDigit = parseInt(s.substring(i-2, i));
        if (twoDigit >= 10 && twoDigit <= 26) {
            dp[i] += dp[i-2];
        }
    }
    
    return dp[s.length];
}

console.log(countDecodings('111'));  // 3
console.log(countDecodings('226'));  // 3
console.log(countDecodings('2101')); // 1
3
3
1

Comparison

Approach Time Complexity Space Complexity Best For
Recursive O(2^n) O(n) Small inputs, learning
Dynamic Programming O(n) O(n) Large inputs, production

Conclusion

The recursive solution explores all possible decoding paths, while dynamic programming optimizes by storing intermediate results. Both approaches correctly count the number of ways to decode a numeric message back into alphabetic combinations.

Updated on: 2026-03-15T23:19:00+05:30

276 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements