Count of Subarrays not containing all elements of another Array
Given two arrays nums[] of size N and target[]. The task is to find the number of non-empty subarrays of nums[] that do not contain every number in the target[]. As the answer can be very large, calculate the result modulo 109+7.
Examples:
Input: nums = {1, 2, 2}, target = {1, 2}
Output: 4
Explanation: The subarrays that don’t contain both 1 and 2 in nums[] are:
{1}, {2}, {2}, {2, 2}Input: nums = {1, 2, 3}, target = {1}
Output: 3
Explanation: The subarrays are {2}, {3}, {2, 3}.
Approach: The simple approach to solving this problem is based on the below idea:
- Find the number of subarrays that contain all the elements of the target[] array.
- If there are X such subarrays, then the number of subarrays not containing all the elements will be [N*(N+1)/2 – X], where N*(N+1)/2 are the total number of subarrays of array nums[].
- Here use the concept of two pointer to find the number X and get desired output using the above formula.
Follow the steps mentioned below:
- Maintain all the numbers in an unordered set as well as keep the frequency count of all these numbers in a map.
- Now use the two pointer approach with a left and a right pointer.
- Advance the right endpoint until every number in the target is found in that window.
- Once we do so, count how many subarrays start at left that contains every number in target and advance left until there are no longer all elements of the target[].
- Keep subtracting the subarray that contains every number in target from the total subarray which will yield the final required answer.
Below is the implementation of the above approach.
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; const int MOD = 1000000007; // Function to count subarrays that // do not contain target array int countSubarrays(vector< int >& nums, vector< int >& target) { // Size of nums int N = nums.size(); // The total number of subarrays in nums[] long long ans = N * (N + 1LL) / 2; // Map to store frequency unordered_map< int , int > freq; unordered_set< int > active(target.begin(), target.end()); // Left pointer as mentioned above int left = 0; // Right pointer loop until all elements // in target are present for ( int right = 0; right < N; right++) { // Populating the frequency // of elements in freq map if (active.count(nums[right])) freq[nums[right]]++; // When there is the possibility // that it contains the subarray // target then only target and // freq size will be equal while (freq.size() == target.size()) { // Total subarray-count of // subarray which contains // target = Count of // subarray which does not // contain target which is // our required ans ans -= (N - right); if (active.count(nums[left])) { if (--freq[nums[left]] == 0) // erasing element // frequency from left // pointer freq.erase(nums[left]); } // Advance the left pointer // until we no longer have // every number in target left++; } } // Returning ans mod 10^9+7 return ans % MOD; } // Driver code int main() { vector< int > nums = { 1, 2, 2 }; vector< int > target = { 1, 2 }; // Function call cout << countSubarrays(nums, target); return 0; } |
Java
// Java code to implement the approach import java.util.*; class GFG{ static int MOD = 1000000007 ; // Function to count subarrays that // do not contain target array static int countSubarrays(Integer[]nums, Integer[] target) { // Size of nums int N = nums.length; // The total number of subarrays in nums[] long ans = N * (N + 1 ) / 2 ; // Map to store frequency HashMap<Integer,Integer> freq = new HashMap<Integer,Integer> (); HashSet<Integer> active = new HashSet<Integer>(); active.addAll(Arrays.asList(target)); // Left pointer as mentioned above int left = 0 ; // Right pointer loop until all elements // in target are present for ( int right = 0 ; right < N; right++) { // Populating the frequency // of elements in freq map if (active.contains(nums[right])) if (freq.containsKey(nums[right])){ freq.put(nums[right], freq.get(nums[right])+ 1 ); } else { freq.put(nums[right], 1 ); } // When there is the possibility // that it contains the subarray // target then only target and // freq size will be equal while (freq.size() == target.length) { // Total subarray-count of // subarray which contains // target = Count of // subarray which does not // contain target which is // our required ans ans -= (N - right); if (active.contains(nums[left])) { if (freq.get(nums[left])- 1 == 0 ) // erasing element // frequency from left // pointer freq.remove(nums[left]); } // Advance the left pointer // until we no longer have // every number in target left++; } } // Returning ans mod 10^9+7 return ( int ) (ans % MOD); } // Driver code public static void main(String[] args) { Integer[] nums = { 1 , 2 , 2 }; Integer[] target = { 1 , 2 }; // Function call System.out.print(countSubarrays(nums, target)); } } // This code is contributed by 29AjayKumar |
Python3
# python3 code to implement the approach MOD = 1000000007 # Function to count subarrays that # do not contain target array def countSubarrays(nums, target) : # Size of nums N = len (nums) # The total number of subarrays in nums[] ans = N * (N + 1 ) / / 2 # Map to store frequency freq = {} active = set (target) # Left pointer as mentioned above left = 0 # Right pointer loop until all elements # in target are present for right in range ( 0 , N) : # Populating the frequency # of elements in freq map if ( nums[right] in active) : freq[nums[right]] = freq[nums[right]] + 1 if nums[right] in freq else 1 # When there is the possibility # that it contains the subarray # target then only target and # freq size will be equal while ( len (freq) = = len (target)) : # Total subarray-count of # subarray which contains # target = Count of # subarray which does not # contain target which is # our required ans ans - = (N - right) if ( nums[left] in active) : if ( nums[left] in freq ) : # erasing element # frequency from left # pointer if freq[nums[left]] = = 1 : del freq[nums[left]] else : freq[nums[left]] - = 1 # Advance the left pointer # until we no longer have # every number in target left + = 1 # Returning ans mod 10^9+7 return ans % MOD # Driver code if __name__ = = "__main__" : nums = [ 1 , 2 , 2 ] target = [ 1 , 2 ] # Function call print (countSubarrays(nums, target)) # This code is contributed by rakeshsahni |
C#
// C# program to implement above approach using System; using System.Collections.Generic; class GFG { public static int MOD = 1000000007; // Function to count subarrays that // do not contain target array public static int countSubarrays(List< int > nums, List< int > target) { // Size of nums int N = nums.Count; // The total number of subarrays in nums[] long ans = (( long )N * ( long )(N + 1))/2; // Map to store frequency Dictionary< int , int > freq = new Dictionary< int , int >(); HashSet< int > active = new HashSet< int >(target); // Left pointer as mentioned above int left = 0; // Right pointer loop until all elements // in target are present for ( int right = 0; right < N; right++) { // Populating the frequency // of elements in freq map if (active.Contains(nums[right])){ int val; if (freq.TryGetValue(nums[right], out val)) { // yay, value exists! freq[nums[right]] = val + 1; } else { // darn, lets add the value freq.Add(nums[right], 1); } } // When there is the possibility // that it contains the subarray // target then only target and // freq size will be equal while (freq.Count == target.Count) { // Total subarray-count of // subarray which contains // target = Count of // subarray which does not // contain target which is // our required ans ans -= (N - right); if (active.Contains(nums[left])) { --freq[nums[left]]; if (freq[nums[left]] == 0){ // erasing element // frequency from left // pointer freq.Remove(nums[left]); } } // Advance the left pointer // until we no longer have // every number in target left++; } } // Returning ans mod 10^9+7 return ( int )(ans % MOD); } // Driver Code public static void Main( string [] args) { // Input Array List< int > nums = new List< int >{ 1, 2, 2 }; List< int > target = new List< int >{ 1, 2 }; // Function call and printing result. Console.Write(countSubarrays(nums, target)); } } // This code is contributed by subhamgoyal2014. |
Javascript
<script> // JavaScript code to implement the approach const MOD = 1000000007 // Function to count subarrays that // do not contain target array function countSubarrays(nums, target){ // Size of nums let N = nums.length // The total number of subarrays in nums[] let ans =Math.floor(N * (N + 1) / 2) // Map to store frequency let freq = new Map() let active = new Set() for (let i of target){ active.add(i) } // Left pointer as mentioned above let left = 0 // Right pointer loop until all elements // in target are present for (let right=0;right<N;right++){ // Populating the frequency // of elements in freq map if (active.has(nums[right])){ freq.set(nums[right], freq.has(nums[right])?freq[nums[right]] + 1:1) } // When there is the possibility // that it contains the subarray // target then only target and // freq size will be equal while (freq.size == target.length){ // Total subarray-count of // subarray which contains // target = Count of // subarray which does not // contain target which is // our required ans ans -= (N - right) if (active.has(nums[left])){ if (freq.has(nums[left])){ // erasing element // frequency from left // pointer if (freq.get(nums[left]) == 1) freq. delete (nums[left]) else freq.set(nums[left], freq.get(nums[left])- 1) } } // Advance the left pointer // until we no longer have // every number in target left += 1 } } // Returning ans mod 10^9+7 return ans % MOD } // Driver code let nums = [ 1, 2, 2 ] let target = [ 1, 2 ] // Function call document.write(countSubarrays(nums, target), "</br>" ) // This code is contributed by shinjanpatra <script> |
4
Time Complexity:
Auxiliary Space:
Brute Force in Python:
Approach:
- Initialize a variable “count” to 0.
- Use nested loops to iterate through all possible subarrays of the given input array “nums“.
- For each subarray, check if it contains all the elements of the target array “target“.
- If it does not contain all the elements of the target array, increment the “count” variable.
- Return the “count” variable as the output.
Python3
def count_subarrays(nums, target): count = 0 for i in range ( len (nums)): for j in range (i, len (nums)): if not all (x in nums[i:j + 1 ] for x in target): count + = 1 return count # Example inputs nums1 = [ 1 , 2 , 2 ] target1 = [ 1 , 2 ] nums2 = [ 1 , 2 , 3 ] target2 = [ 1 ] # Outputs print (count_subarrays(nums1, target1)) # Output: 4 print (count_subarrays(nums2, target2)) # Output: 3 |
4 3
Time Complexity: O(n^3) where n is the length of the input array.
Space Complexity: O(1)
Please Login to comment...