Skip to content
Related Articles

Related Articles

Count Possible Decodings of a given Digit Sequence
  • Difficulty Level : Medium
  • Last Updated : 31 Mar, 2021

Let 1 represent ‘A’, 2 represents ‘B’, etc. Given a digit sequence, count the number of possible decodings of the given digit sequence. 

Examples: 

Input:  digits[] = "121"
Output: 3
// The possible decodings are "ABA", "AU", "LA"

Input: digits[] = "1234"
Output: 3
// The possible decodings are "ABCD", "LCD", "AWD"

An empty digit sequence is considered to have one decoding. It may be assumed that the input contains valid digits from 0 to 9 and there are no leading 0’s, no extra trailing 0’s, and no two or more consecutive 0’s.

This problem is recursive and can be broken into sub-problems. We start from the end of the given digit sequence. We initialize the total count of decodings as 0. We recur for two subproblems. 
1) If the last digit is non-zero, recur for the remaining (n-1) digits and add the result to the total count. 
2) If the last two digits form a valid character (or smaller than 27), recur for remaining (n-2) digits and add the result to the total count.

Following is the implementation of the above approach.  



C++




// C++ implementation to count number of
// decodings that can be formed from a
// given digit sequence
#include <cstring>
#include <iostream>
using namespace std;
 
// recuring function to find
// ways in how many ways a
// string can be decoded of length
// greater than 0 and starting with
// digit 1 and greater.
int countDecoding(char* digits, int n)
{
    // base cases
    if (n == 0 || n == 1)
        return 1;
    if (digits[0] == '0')
        return 0;
 
    // for base condition "01123" should return 0
    // Initialize count
    int count = 0;
 
    // If the last digit is not 0,
    // then last digit must add
    // to the number of words
    if (digits[n - 1] > '0')
        count = countDecoding(digits, n - 1);
 
    // If the last two digits form a number smaller
    // than or equal to 26, then consider
    // last two digits and recur
    if (digits[n - 2] == '1'
        || (digits[n - 2] == '2'
        && digits[n - 1] < '7'))
        count += countDecoding(digits, n - 2);
 
    return count;
}
 
// Given a digit sequence of length n,
// returns count of possible decodings by
// replacing 1 with A, 2 woth B, ... 26 with Z
int countWays(char* digits, int n)
{
    if (n == 0 || (n == 1 && digits[0] == '0'))
        return 0;
    return countDecoding(digits, n);
}
 
// Driver code
int main()
{
    char digits[] = "1234";
    int n = strlen(digits);
    cout << "Count is " << countWays(digits, n);
    return 0;
}
// Modified by Atanu Sen

Java




// A naive recursive Java implementation
// to count number of decodings that
// can be formed from a given digit sequence
 
class GFG {
 
    // recuring function to find
    // ways in how many ways a
    // string can be decoded of length
    // greater than 0 and starting with
    // digit 1 and greater.
    static int countDecoding(char[] digits, int n)
    {
        // base cases
        if (n == 0 || n == 1)
            return 1;
 
        // for base condition "01123" should return 0
        if (digits[0] == '0')
            return 0;
 
        // Initialize count
        int count = 0;
 
        // If the last digit is not 0, then
        // last digit must add to
        // the number of words
        if (digits[n - 1] > '0')
            count = countDecoding(digits, n - 1);
 
        // If the last two digits form a number
        // smaller than or equal to 26,
        // then consider last two digits and recur
        if (digits[n - 2] == '1'
            || (digits[n - 2] == '2'
                && digits[n - 1] < '7'))
            count += countDecoding(digits, n - 2);
 
        return count;
    }
 
    // Given a digit sequence of length n,
    // returns count of possible decodings by
    // replacing 1 with A, 2 woth B, ... 26 with Z
    static int countWays(char[] digits, int n)
    {
        if (n == 0 || (n == 1 && digits[0] == '0'))
            return 0;
        return countDecoding(digits, n);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        char digits[] = { '1', '2', '3', '4' };
        int n = digits.length;
        System.out.printf("Count is %d",
                          countWays(digits, n));
    }
}
 
// This code is contributed by Smitha Dinesh Semwal.
// Modified by Atanu Sen

Python3




# Recursive implementation of numDecodings
def numDecodings(s: str) -> int:
    if len(s) == 0
    or (len(s) == 1
        and s[0] == '0'):
        return 0
    return numDecodingsHelper(s, len(s))
 
 
def numDecodingsHelper(s: str, n: int) -> int:
    if n == 0 or n == 1:
        return 1
    count = 0
    if s[n-1] > "0":
        count = numDecodingsHelper(s, n-1)
    if (s[n - 2] == '1'
        or (s[n - 2] == '2'
            and s[n - 1] < '7')):
        count += numDecodingsHelper(s, n - 2)
    return count
 
 
# Driver code
digits = "1234"
print("Count is ", numDecodings(digits))
# This code is contributed by Frank Hu

C#




// A naive recursive C# implementation
// to count number of decodings that
// can be formed from a given digit sequence
using System;
 
class GFG {
 
    // recuring function to find
    // ways in how many ways a
    // string can be decoded of length
    // greater than 0 and starting with
    // digit 1 and greater.
    static int countDecoding(char[] digits, int n)
    {
 
        // base cases
        if (n == 0 || n == 1)
            return 1;
 
        // Initialize count
        int count = 0;
 
        // If the last digit is not 0, then
        // last digit must add to
        // the number of words
        if (digits[n - 1] > '0')
            count = countDecoding(digits, n - 1);
 
        // If the last two digits form a number
        // smaller than or equal to 26, then
        // consider last two digits and recur
        if (digits[n - 2] == '1'
            || (digits[n - 2] == '2'
                && digits[n - 1] < '7'))
            count += countDecoding(digits, n - 2);
 
        return count;
    }
 
    // Given a digit sequence of length n,
    // returns count of possible decodings by
    // replacing 1 with A, 2 woth B, ... 26 with Z
    static int countWays(char[] digits, int n)
    {
        if (n == 0 || (n == 1 && digits[0] == '0'))
            return 0;
        return countDecoding(digits, n);
    }
 
    // Driver code
    public static void Main()
    {
        char[] digits = { '1', '2', '3', '4' };
        int n = digits.Length;
        Console.Write("Count is ");
        Console.Write(countWays(digits, n));
    }
}
 
// This code is contributed by nitin mittal.

PHP




<?php
// A naive recursive PHP implementation
// to count number of decodings that can
// be formed from a given digit sequence
 
//recuring function to find
//ways in how many ways a
//string can be decoded of length
//greater than 0 and starting with
//digit 1 and greater.
function countDecoding(&$digits, $n)
{
    // base cases
    if ($n == 0 || $n == 1)
        return 1;
 
    $count = 0; // Initialize count
 
    // If the last digit is not 0, then last
    // digit must add to the number of words
    if ($digits[$n - 1] > '0')
        $count = countDecoding($digits, $n - 1);
 
    // If the last two digits form a number
    // smaller than or equal to 26, then
    // consider last two digits and recur
    if ($digits[$n - 2] == '1' ||
       ($digits[$n - 2] == '2' &&
        $digits[$n - 1] < '7') )
        $count += countDecoding($digits, $n - 2);
 
    return $count;
}
 
// Given a digit sequence of length n,
// returns count of possible decodings by
// replacing 1 with A, 2 woth B, ... 26 with Z
function countWays(&$digits, $n){
  if($n==0 || ($n == 1 && $digits[0] == '0'))
     return 0;
  return countDecoding($digits, $n);
}
 
// Driver Code
$digits = "1234";
$n = strlen($digits);
echo "Count is " . countWays($digits, $n);
 
// This code is contributed by ita_c
?>

Javascript




<script>
 
// A naive recursive JavaScript implementation
// to count number of decodings that
// can be formed from a given digit sequence   
     
    // recuring function to find
    // ways in how many ways a
    // string can be decoded of length
    // greater than 0 and starting with
    // digit 1 and greater.
    function countDecoding(digits, n)
    {
        // base cases
        if (n == 0 || n == 1)
        {
            return 1;
        }
        // for base condition "01123" should return 0
        if (digits[0] == '0')
        {
            return 0;
        }
         
        // Initialize count
        let count = 0;
         
        // If the last digit is not 0, then
        // last digit must add to
        // the number of words
        if (digits[n - 1] > '0')
        {
            count = countDecoding(digits, n - 1);
        }
        // If the last two digits form a number
        // smaller than or equal to 26,
        // then consider last two digits and recur
        if (digits[n - 2] == '1'
            || (digits[n - 2] == '2'
                && digits[n - 1] < '7'))
        {
            count += countDecoding(digits, n - 2);
        }
        return count;
    }
    // Given a digit sequence of length n,
    // returns count of possible decodings by
    // replacing 1 with A, 2 woth B, ... 26 with Z
    function countWays(digits, n)
    {
        if (n == 0 || (n == 1 && digits[0] == '0'))
        {
            return 0;
        }
        return countDecoding(digits, n);
    }
     
    // Driver code
    digits=['1', '2', '3', '4'];
    let n = digits.length;
    document.write("Count is ",countWays(digits, n));
     
    // This code is contributed by avanitrachhadiya2155
     
</script>

Output: 

Count is 3

The time complexity of above the code is exponential. If we take a closer look at the above program, we can observe that the recursive solution is similar to Fibonacci Numbers. Therefore, we can optimize the above solution to work in O(n) time using Dynamic Programming

Following is the implementation for the same. 

C++




// A Dynamic Programming based C++
// implementation to count decodings
#include <iostream>
#include <cstring>
using namespace std;
 
// A Dynamic Programming based function
// to count decodings
int countDecodingDP(char *digits, int n)
{
    // A table to store results of subproblems
    int count[n+1];
    count[0] = 1;
    count[1] = 1;
    //for base condition "01123" should return 0
    if(digits[0]=='0'
         return 0;
    for (int i = 2; i <= n; i++)
    {
        count[i] = 0;
 
        // If the last digit is not 0,
        // then last digit must add to the number of words
        if (digits[i-1] > '0')
            count[i] = count[i-1];
 
        // If second last digit is smaller
        // than 2 and last digit is smaller than 7,
        // then last two digits form a valid character
        if (digits[i-2] == '1' ||
              (digits[i-2] == '2' && digits[i-1] < '7') )
            count[i] += count[i-2];
    }
    return count[n];
}
 
// Driver program to test above function
int main()
{
    char digits[] = "1234";
    int n = strlen(digits);
    cout << "Count is " << countDecodingDP(digits, n);
    return 0;
}
// Modified by Atanu Sen

Java




// A Dynamic Programming based Java
// implementation to count decodings
import java.io.*;
 
class GFG
{
     
// A Dynamic Programming based
// function to count decodings
static int countDecodingDP(char digits[],
                           int n)
{
    // A table to store results of subproblems
    int count[] = new int[n + 1];
    count[0] = 1;
    count[1] = 1;
    if(digits[0]=='0')   //for base condition "01123" should return 0
          return 0;
    for (int i = 2; i <= n; i++)
    {
        count[i] = 0;
 
        // If the last digit is not 0,
        // then last digit must add to
        // the number of words
        if (digits[i - 1] > '0')
            count[i] = count[i - 1];
 
        // If second last digit is smaller
        // than 2 and last digit is smaller
        // than 7, then last two digits
        // form a valid character
        if (digits[i - 2] == '1' ||
           (digits[i - 2] == '2' &&
            digits[i - 1] < '7'))
            count[i] += count[i - 2];
    }
    return count[n];
}
 
// Driver Code
public static void main (String[] args)
{
    char digits[] = {'1','2','3','4'};
    int n = digits.length;
    System.out.println("Count is " +
               countDecodingDP(digits, n));
}
}
 
// This code is contributed by anuj_67
// Modified by Atanu Sen

Python3




# A Dynamic Programming based Python3
# implementation to count decodings
 
# A Dynamic Programming based function
# to count decodings
def countDecodingDP(digits, n):
 
    count = [0] * (n + 1); # A table to store
                           # results of subproblems
    count[0] = 1;
    count[1] = 1;
 
    for i in range(2, n + 1):
 
        count[i] = 0;
 
        # If the last digit is not 0, then last
        # digit must add to the number of words
        if (digits[i - 1] > '0'):
            count[i] = count[i - 1];
 
        # If second last digit is smaller than 2
        # and last digit is smaller than 7, then
        # last two digits form a valid character
        if (digits[i - 2] == '1' or
           (digits[i - 2] == '2' and
            digits[i - 1] < '7') ):
            count[i] += count[i - 2];
 
    return count[n];
 
# Driver Code
digits = "1234";
n = len(digits);
print("Count is" ,
       countDecodingDP(digits, n));
 
# This code is contributed by mits

C#




// A Dynamic Programming based C#
// implementation to count decodings
using System;
 
class GFG
{
     
// A Dynamic Programming based
// function to count decodings
static int countDecodingDP(char[] digits,
                           int n)
{
    // A table to store results of subproblems
    int[] count = new int[n + 1];
    count[0] = 1;
    count[1] = 1;
 
    for (int i = 2; i <= n; i++)
    {
        count[i] = 0;
 
        // If the last digit is not 0,
        // then last digit must add to
        // the number of words
        if (digits[i - 1] > '0')
            count[i] = count[i - 1];
 
        // If second last digit is smaller
        // than 2 and last digit is smaller
        // than 7, then last two digits
        // form a valid character
        if (digits[i - 2] == '1' ||
           (digits[i - 2] == '2' &&
            digits[i - 1] < '7'))
            count[i] += count[i - 2];
    }
    return count[n];
}
 
// Driver Code
public static void Main()
{
    char[] digits = {'1','2','3','4'};
    int n = digits.Length;
    Console.WriteLine("Count is " +
            countDecodingDP(digits, n));
}
}
 
// This code is contributed
// by Akanksha Rai
// Modified by Atanu Sen

PHP




<?php
// A Dynamic Programming based
// php implementation to count decodings
 
// A Dynamic Programming based function to count decodings
function countDecodingDP($digits, $n)
{
    // A table to store results of subproblems
    $count[$n+1]=array();
    $count[0] = 1;
    $count[1] = 1;
 
    for ($i = 2; $i <= $n; $i++)
    {
        $count[$i] = 0;
 
        // If the last digit is not 0, then last digit must add to
        // the number of words
        if ($digits[$i-1] > '0')
            $count[$i] = $count[$i-1];
 
        // If second last digit is smaller than 2 and last digit is
        // smaller than 7, then last two digits form a valid character
        if ($digits[$i-2] == '1' || ($digits[$i-2] == '2' && $digits[$i-1] < '7') )
            $count[$i] += $count[$i-2];
    }
    return $count[$n];
}
 
// Driver program to test above function
    $digits = "1234";
    $n = strlen($digits);
    echo  "Count is " , countDecodingDP($digits, $n);
 
#This code is contributed by ajit.
?>

Javascript




<script>
 
// A Dynamic Programming based Javascript
// implementation to count decodings
 
// A Dynamic Programming based
// function to count decodings
function countDecodingDP(digits, n)
{
     
    // A table to store results of subproblems
    let count = new Array(n + 1);
    count[0] = 1;
    count[1] = 1;
     
    // For base condition "01123" should return 0
    if (digits[0] == '0')  
          return 0;
           
    for(let i = 2; i <= n; i++)
    {
        count[i] = 0;
  
        // If the last digit is not 0,
        // then last digit must add to
        // the number of words
        if (digits[i - 1] > '0')
            count[i] = count[i - 1];
  
        // If second last digit is smaller
        // than 2 and last digit is smaller
        // than 7, then last two digits
        // form a valid character
        if (digits[i - 2] == '1' ||
           (digits[i - 2] == '2' &&
            digits[i - 1] < '7'))
            count[i] += count[i - 2];
    }
    return count[n];
}
 
// Driver Code
let digits = [ '1','2','3','4' ];
let n = digits.length;
 
document.write("Count is " +
               countDecodingDP(digits, n));
                
// This code is contributed by rag2127
     
</script>

Output: 

Count is 3

Time Complexity of the above solution is O(n) and it requires O(n) auxiliary space. We can reduce auxiliary space to O(1) by using the space-optimized version discussed in the Fibonacci Number Post
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
 

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :