Count Subsequences with ordered integers in Array
Given an array nums[] of N positive integers, the task is to find the number of subsequences that can be created from the array where each subsequence contains all integers from 1 to its size in any order. If two subsequences have different chosen indices, then they are considered different.
Examples:
Input: N = 5, nums = {1, 2, 3, 2, 4}
Output: 7
Explanation: There are 7 subsequences present in the given array which has the size of M and contains integers from 1 to M. The subsequences are: [1], [1, 2], [1, 2], [1, 2, 3], [1, 3, 2], [1, 2, 3, 4], and [1, 3, 2, 4]Input: N = 7, nums = {1, 3, 5, 8, 9, 8, 2}
Output: 3
Explanation: The three subsequences present in the given array are: [1], [1, 2], and [1, 3, 2].
Approach: This can be solved with the following idea:
First of all, we will make a frequency map using the hash map. Suppose we have given the array, nums = [1, 2, 3, 2, 4] then the frequency map will be like:
[[1 -> 1], [2 -> 2], [3 -> 1], [4 -> 1]].
- Now we will start iterating from i = 1, we will continue the iteration till the frequency map contains a key equal to i.
- As for i = 2, the above case has a frequency value of 2, now we will check how many arrays we can make using i = 1, and we know it is 1, therefore the number of arrays we can make of size 2 such that it contains elements 1 and 2 will be: (number of arrays we can make of size 1) * (frequency value of 2). For the above case, it will be: 1 * 2 = 2, so till i = 2 we can make two arrays of size 2 and 1 array of size 1, the total value(answer variable) will be: 2 + 1 = 3.
- For i = 3, the above case has a frequency value of 1, and the number of arrays we can create of size 2 is 2, so the number of arrays of size 3 we can create will be: (2 * 1) = 2, answer variable will get updated as: 3 + 2 = 5.
- For i = 4, the above case has a frequency value of 1, and the number of arrays we can create of size 2 is 2, so the number of arrays of size 4 we can create will be: (2 * 1) = 2, answer variable will get updated as: 5 + 2 = 7.
To implement the above intuition follow the below-given steps:
- Firstly, make a hash map freq, which stores the frequency value of every element.
- Initialize our answer variable with a frequency value of 1 and also initialize a last variable which contains the value of a number of arrays we can make of size i – 1.
- Start iterating with i = 2, until it doesn’t contain in the frequency map.
- For every i, find a number of arrays you can make and update it in the answer variable also don’t forget to take modulo with 1000000007.
- Return the answer.
Below is the implementation of the above approach:
C++
// C++ algorithm for the above approach #include <iostream> #include <unordered_map> using namespace std; // Function which will return number // of arrays we can make int makeArrays( int nums[], int N) { // Making frequency map of the given array nums unordered_map< int , int > freq; for ( int i = 0; i < N; i++) { freq[nums[i]] = freq[nums[i]] + 1; } long long mod = 1000000007; // Initializing ans variable long long ans = (freq.count(1)) ? freq[1] : 0; // Initializing last variable long long last = ans; int i = 2; // Iterating after i = 1 while (freq.count(i)) { last = (last * freq[i]) % mod; ans = (ans + last) % mod; i++; } // Returning answer return static_cast < int >(ans); } // Driver Code int main() { int nums[] = { 1, 3, 5, 8, 9, 8, 2 }; int N = sizeof (nums) / sizeof (nums[0]); cout << makeArrays(nums, N) << endl; return 0; } |
Java
// Java algorithm for above approach import java.util.*; class GFG { // Driver Code public static void main(String[] args) { int [] nums = { 1 , 3 , 5 , 8 , 9 , 8 , 2 }; int N = nums.length; System.out.println(makeArrays(nums, N)); } // Function which will return number // of arrays we can make public static int makeArrays( int [] nums, int N) { // Making frequency map of // the given array nums Map<Integer, Integer> freq = new HashMap<>(); for ( int i = 0 ; i < N; i++) { freq.put(nums[i], freq.getOrDefault(nums[i], 0 ) + 1 ); } long mod = 1000000007 ; // Initializing ans variable long ans = (freq.containsKey( 1 )) ? freq.get( 1 ) : 0 ; // Initializing last variable long last = ans; int i = 2 ; // Iterating after i = 1 while (freq.containsKey(i)) { last = (last * freq.get(i)) % mod; ans = (ans + last) % mod; i++; } // Returning answer return ( int )(ans); } } |
Python3
def make_arrays(nums): freq = {} # Count the frequency of each number for num in nums: freq[num] = freq.get(num, 0 ) + 1 mod = 1000000007 ans = freq.get( 1 , 0 ) last = ans i = 2 # Iterate over the numbers and calculate the answer while i in freq: last = (last * freq[i]) % mod ans = (ans + last) % mod i + = 1 # Return the answer return ans # Example usage nums = [ 1 , 3 , 5 , 8 , 9 , 8 , 2 ] print (make_arrays(nums)) # Output: 7 |
C#
// C# program for above approach using System; using System.Collections.Generic; class GFG { // Function which will return number // of arrays we can make static int makeArrays( int [] nums, int N) { // Making frequency map of // the given array nums Dictionary< int , int > freq = new Dictionary< int , int >(); int i; for (i = 0; i < N; i++) { if (freq.ContainsKey(nums[i])) freq[nums[i]]++; else freq.Add(nums[i], 1); } long mod = 1000000007; // Initializing ans variable long ans = (freq.ContainsKey(1)) ? freq[1] : 0; // Initializing last variable long last = ans; i = 2; // Iterating after i = 1 while (freq.ContainsKey(i)) { last = (last * freq[i]) % mod; ans = (ans + last) % mod; i++; } // Returning answer return ( int )(ans); } // Driver Code public static void Main() { int [] nums = { 1, 3, 5, 8, 9, 8, 2 }; int N = nums.Length; Console.Write(makeArrays(nums, N)); } } // This code is contributed by Tapesh(tapeshdua420) |
Javascript
// Function which will return number of arrays we can make function makeArrays(nums) { // Making frequency map of the given array nums const freq = new Map(); for (let i = 0; i < nums.length; i++) { freq.set(nums[i], (freq.get(nums[i]) || 0) + 1); } const mod = 1000000007; // Initializing ans variable let ans = freq.has(1) ? freq.get(1) : 0; // Initializing last variable let last = ans; let i = 2; // Iterating after i = 1 while (freq.has(i)) { last = (last * freq.get(i)) % mod; ans = (ans + last) % mod; i++; } // Returning answer return ans; } // Driver Code const nums = [1, 3, 5, 8, 9, 8, 2]; console.log(makeArrays(nums)); |
3
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...