Open In App

Count of subsequences of Array with last digit of product as K

Last Updated : 30 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A[] of size N and a digit K. Find the number of sub-sequences of the array where the last digit of the product of the elements of the sub-sequence is K.

Example:

Input:  A = {2, 3, 4, 2}, K = 2
Output: 4
Explanation:  sub-sequences with product’s last digit = 2 are: {2}, {2}, {2, 3, 2}, {3, 4}

Input: A = {1, 1, 1, 2}, K = 1
Output: 7
Explanation: The sub-sequences with product’s last digit = 2 are: {1}, {1}, {1}, {1, 1}, {1, 1}, {1, 1},  {1, 1, 1}

 

Approach: The above problem can be solved using recursion based on below idea:

We will use the recursive approach to find each possible sub-sequences, and on the go we will calculate the product of the elements and keep track of the last digit p, then at end we check if p is equal to K we return 1 else return 0. 

Illustration:

Note: during multiplication of two numbers say a = 133 and b = 26
 133
x 26
——
1798   <— last digit gets multiplied only once
266X
——
3458   (3*6 = 18,  both have 8 as last digits)
So the last digit of the a*b will be equal to the last digit of product of last digits of a and b 
Suppose we have numbers 11, 233, 783, 4759, 6
product of the numbers = 57302995266
product of just the last digits, i.e., 1, 3, 3, 9, 6 = 486
Both have last digit as 6 

Follow the below steps to solve the problem:

  • Base Case: if p is equal to K return 1, else return 0
  • There are two options either take the element or don’t.
    • if we take the element, then the product p gets updated to p*a[n-1], as we are just bothered about the last digit so we can just update p to the last digit of p*a[n-1], i.e., p becomes p*a[n-1]%10.
    • other option is don’t take the element, so don’t update p and do n-1, to look for other possibilities.
  • As we need the total number of such sub-sequences we return the sum of the above two calls.
  • An edge case is if K=1, then we will get one extra sub-sequence that is an empty sub-sequence, as we initially take p=1 so in an empty sub-sequence we get p==k and 1 is returned. So when K==1 we deduct 1 from the answer. 

Time Complexity:  O(2N)
Auxiliary Space:  O(N)

Efficient Approach: Since Recursion takes exponential time complexity, the above recursive approach can be optimized further using Dynamic Programming. We will construct a look-up table and memoize the recursive code in order to do so.

Below is the implementation of the above approach:

C++




// C++ program for Count the number of
// sub-sequences of an  array where the last digit
// of the product of the subsequence is K.
#include <bits/stdc++.h>
using namespace std;
 
int dp[1001][10];
// recursive utility function
int countSubsequencesUtil(int n, int k, int p,
                          vector<int>& a)
{
    // Base case
    if (n == 0) {
        if (p == k)
            return 1;
        else
            return 0;
    }
 
    // return pre calculated value from
    // look-up table
    if (dp[n][p] != -1)
        return dp[n][p];
 
    // return the total number obtained through
    // option1 and option2
    return dp[n][p]
           = countSubsequencesUtil(n - 1, k,
                                   (p * a[n - 1]) % 10, a)
             + countSubsequencesUtil(n - 1, k, p, a);
}
// Function to  Count the number of subsequences
int countSubsequences(vector<int>& a, int k)
{
    // initialize the table with -1
    memset(dp, -1, sizeof(dp));
 
    int n = a.size();
    int ans = countSubsequencesUtil(n, k, 1, a);
 
    // if k is 1 return 1 less
    if (k == 1)
        return ans - 1;
 
    return ans;
}
 
// Driver Code
int main()
{
    vector<int> a = { 2, 3, 4, 2 };
    int k = 2;
 
    cout << countSubsequences(a, k);
 
    return 0;
}


Java




// Java program to count the number of subsequences
// of an array where the last digit of the product
// of the subsequence is K
import java.io.*;
import java.util.*;
 
public class GFG {
 
  static int[][] dp = new int[1001][10];
 
  // recursive utility function
  static int countSubsequencesUtil(int n, int k, int p,
                                   int[] a)
  {
    // base case
    if (n == 0) {
      if (p == k)
        return 1;
      return 0;
    }
 
    // return pre calculated value from
    // look up table
    if (dp[n][p] != -1)
      return dp[n][p];
 
    // return the total no. obtained through
    // option1 and option2
    return dp[n][p]
      = countSubsequencesUtil(n - 1, k,
                              (p * a[n - 1]) % 10, a)
      + countSubsequencesUtil(n - 1, k, p, a);
  }
 
  // function to count the number of subsequences
  static int countSubsequences(int[] a, int k)
  {
 
    // initializing all elements of table with -1
    for (int i = 0; i <= 1000; i++) {
      for (int j = 0; j < 10; j++) {
        dp[i][j] = -1;
      }
    }
 
    int n = a.length;
    int ans = countSubsequencesUtil(n, k, 1, a);
 
    // if k is 1 return 1 less
    if (k == 1)
      return ans - 1;
 
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int[] a = { 2, 3, 4, 2 };
    int k = 2;
    System.out.print(countSubsequences(a, k));
  }
}
 
// This code is contributed by phasing17


Python3




# Python implementation of above approach
dp = [[-1]*10]*1001
 
# recursive utility function
def countSubsequencesUtil(n, k, p, a) :
     
    # Base case
    if (n == 0) :
        if (p == k):
            return 1
        else:
            return 0
     
    # return pre calculated value from
    # look-up table
    if (dp[n][p] != -1):
        return dp[n][p]
 
    # return the total number obtained through
    # option1 and option2
    dp[n][p] = (countSubsequencesUtil(n - 1, k,(p * a[n - 1]) % 10, a) +
                    countSubsequencesUtil(n - 1, k, p, a));
    return (dp[n][p]);
 
# Function to  Count the number of subsequences
def countSubsequences(a, k) :
 
    n = len(a)
    ans = countSubsequencesUtil(n, k, 1, a)
 
    # if k is 1 return 1 less
    if (k == 1) :
        return (ans - 1)
 
    return ans + 1
 
# Driver Code
a = [ 2, 3, 4, 2 ]
k = 2
 
print(countSubsequences(a, k))
 
# This code is contributed by sanjoy_62.


C#




// C# program for Count the number of
// sub-sequences of an  array where the last digit
// of the product of the subsequence is K.
using System;
class GFG {
 
    static int[, ] dp = new int[1001, 10];
    // recursive utility function
    static int countSubsequencesUtil(int n, int k, int p,
                                     int[] a)
    {
        // Base case
        if (n == 0) {
            if (p == k)
                return 1;
            else
                return 0;
        }
 
        // return pre calculated value from
        // look-up table
        if (dp[n, p] != -1)
            return dp[n, p];
 
        // return the total number obtained through
        // option1 and option2
        return dp[n, p]
            = countSubsequencesUtil(n - 1, k,
                                    (p * a[n - 1]) % 10, a)
              + countSubsequencesUtil(n - 1, k, p, a);
    }
    // Function to  Count the number of subsequences
    static int countSubsequences(int[] a, int k)
    {
        // initialize the table with -1
        for (int i = 0; i < 1001; i++) {
            for (int j = 0; j < 10; j++) {
                dp[i, j] = -1;
            }
        }
 
        int n = a.Length;
        int ans = countSubsequencesUtil(n, k, 1, a);
 
        // if k is 1 return 1 less
        if (k == 1)
            return ans - 1;
 
        return ans;
    }
 
    // Driver Code
    public static void Main()
    {
        int[] a = { 2, 3, 4, 2 };
        int k = 2;
 
        Console.Write(countSubsequences(a, k));
    }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
 
// JavaScript program for Count the number of
// sub-sequences of an  array where the last digit
// of the product of the subsequence is K.
 
// initialize the dp table with -1
let dp = new Array(1001)
for(let i = 0; i < 1001; i++)
{
    dp[i] = new Array(10).fill(-1)
}
 
// recursive utility function
function countSubsequencesUtil(n, k, p,a)
{
    // Base case
    if (n == 0) {
        if (p == k)
            return 1
        else
            return 0
    }
 
    // return pre calculated value from
    // look-up table
    if (dp[n][p] != -1)
        return dp[n][p]
 
    // return the total number obtained through
    // option1 and option2
    return dp[n][p] = countSubsequencesUtil(n - 1, k, (p * a[n - 1]) % 10, a) + countSubsequencesUtil(n - 1, k, p, a)
}
 
// Function to  Count the number of subsequences
function countSubsequences(a,k)
{
 
    let n = a.length
    let ans = countSubsequencesUtil(n, k, 1, a)
 
    // if k is 1 return 1 less
    if (k == 1)
        return ans - 1;
 
    return ans;
}
 
// Driver Code
let a = [ 2, 3, 4, 2 ]
let k = 2
 
document.write(countSubsequences(a, k))
 
// This code is contributed by shinjanpatra.
</script>


Output

4

Time Complexity:  O(N)
Auxiliary Space:  O(N)

Efficient approach : Using DP Tabulation method ( Iterative approach )

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls.

Steps to solve this problem :

  • Create a table to store the solution of the subproblems.
  • Initialize the table with base cases
  • Fill up the table iteratively
  • Return the final solution

Implementation :

C++




// C++ program to count the number of subsequences
// of an array where the last digit of the product
// of the subsequence is k
#include <bits/stdc++.h>
using namespace std;
 
int dp[1001][10];
 
// Function to count the number of subsequences
int countSubsequences(vector<int>& a, int k)
{
    int n = a.size();
 
    // Initialize dp table
    for (int i = 0; i < n; i++) {
        // mark the element's remainder with 10 as 1
        dp[i][a[i] % 10] = 1;
    }
 
    // Fill dp table
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < 10; j++) {
            // add the results of previous cells
            dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a[i]) % 10];
        }
    }
 
    // Return answer
    return dp[n - 1][k];
}
 
// Driver code
int main()
{
    vector<int> a = { 2, 3, 4, 2 };
    int k = 2;
    // function
    cout << countSubsequences(a, k);
 
    return 0;
}
 
// this code is contributed by bhardwajji


Java




import java.util.*;
 
public class Main {
    static int[][] dp = new int[1001][10];
 
    // Function to count the number of subsequences
    static int countSubsequences(List<Integer> a, int k) {
        int n = a.size();
 
        // Initialize dp table
        for (int i = 0; i < n; i++) {
            // mark the element's remainder with 10 as 1
            dp[i][a.get(i) % 10] = 1;
        }
 
        // Fill dp table
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < 10; j++) {
                // add the results of previous cells
                dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a.get(i)) % 10];
            }
        }
 
        // Return answer
        return dp[n - 1][k];
    }
 
    public static void main(String[] args) {
        List<Integer> a = Arrays.asList(2, 3, 4, 2);
        int k = 2;
        // function call
        System.out.println(countSubsequences(a, k));
    }
}


Python3




# Function to count the number of subsequences
def count_subsequences(a, k):
    n = len(a)
    dp = [[0] * 10 for i in range(n)]
 
    # Initialize dp table
    for i in range(n):
        # mark the element's remainder with 10 as 1
        dp[i][a[i] % 10] = 1
 
    # Fill dp table
    for i in range(1, n):
        for j in range(10):
            # add the results of previous cells
            dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a[i]) % 10]
 
    # Return answer
    return dp[n - 1][k]
 
# Driver code
a = [2, 3, 4, 2]
k = 2
 
# function call
print(count_subsequences(a, k))


C#




using System;
using System.Collections.Generic;
 
public class MainClass {
static int[,] dp = new int[1001, 10];
 // Function to count the number of subsequences
static int CountSubsequences(List<int> a, int k) {
    int n = a.Count;
 
    // Initialize dp table
    for (int i = 0; i < n; i++) {
        // mark the element's remainder with 10 as 1
        dp[i, a[i] % 10] = 1;
    }
 
    // Fill dp table
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < 10; j++) {
            // add the results of previous cells
            dp[i, j] += dp[i - 1, j] + dp[i - 1, (j * a[i]) % 10];
        }
    }
 
    // Return answer
    return dp[n - 1, k];
}
 
public static void Main(string[] args) {
    List<int> a = new List<int>() {2, 3, 4, 2};
    int k = 2;
 
    // function call
    Console.WriteLine(CountSubsequences(a, k));
}
}


Javascript




// Function to count the number of subsequences
function count_subsequences(a, k) {
    let n = a.length;
    let dp = Array.from(Array(n), () => Array(10).fill(0));
 
    // Initialize dp table
    for (let i = 0; i < n; i++) {
        // mark the element's remainder with 10 as 1
        dp[i][a[i] % 10] = 1;
    }
 
    // Fill dp table
    for (let i = 1; i < n; i++) {
        for (let j = 0; j < 10; j++) {
            // add the results of previous cells
            dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a[i]) % 10];
        }
    }
 
    // Return answer
    return dp[n - 1][k];
}
 
// Driver code
let a = [2, 3, 4, 2];
let k = 2;
 
// function call
console.log(count_subsequences(a, k));


Output :

4

Time complexity: O(n * 10), where n is the length of the input array.
Auxiliary Space:  O(n * 10).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads