Count of subsequences of Array with last digit of product as K
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> |
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).
Please Login to comment...