Count of Subarrays not containing all elements of another Array
Last Updated : 11 Oct, 2023
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>
Time Complexity: O(N)
Auxiliary Space: O(N)
Brute Force:
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.
C++ #include <iostream> #include <vector> using namespace std; bool containsAll(const vector<int>& nums, int start, int end, const vector<int>& target) { for (int x : target) { bool found = false; for (int i = start; i <= end; i++) { if (nums[i] == x) { found = true; break; } } if (!found) { return false; } } return true; } int countSubarrays(const vector<int>& nums, const vector<int>& target) { int count = 0; int n = nums.size(); for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { if (!containsAll(nums, i, j, target)) { count++; } } } return count; } int main() { vector<int> nums1 = {1, 2, 2}; vector<int> target1 = {1, 2}; vector<int> nums2 = {1, 2, 3}; vector<int> target2 = {1}; cout << countSubarrays(nums1, target1) << endl; // Output: 4 cout << countSubarrays(nums2, target2) << endl; // Output: 3 return 0; }
Java public class CountSubarrays { public static int countSubarrays(int[] nums, int[] target) { int count = 0; int n = nums.length; for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { if (!containsAll(nums, i, j, target)) { count++; } } } return count; } public static boolean containsAll(int[] nums, int start, int end, int[] target) { for (int x : target) { boolean found = false; for (int i = start; i <= end; i++) { if (nums[i] == x) { found = true; break; } } if (!found) { return false; } } return true; } public static void main(String[] args) { int[] nums1 = {1, 2, 2}; int[] target1 = {1, 2}; int[] nums2 = {1, 2, 3}; int[] target2 = {1}; System.out.println(countSubarrays(nums1, target1)); // Output: 4 System.out.println(countSubarrays(nums2, target2)); // Output: 3 } }
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
C# using System; public class CountSubarrays { public static int Countsubarrays(int[] nums, int[] target) { int count = 0; int n = nums.Length; // Loop through all possible subarrays for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { // Check if the subarray contains all elements of the target array if (!ContainsAll(nums, i, j, target)) { count++; } } } return count; } public static bool ContainsAll(int[] nums, int start, int end, int[] target) { foreach (int x in target) { bool found = false; for (int i = start; i <= end; i++) { if (nums[i] == x) { found = true; break; } } if (!found) { return false; } } return true; } public static void Main(string[] args) { int[] nums1 = { 1, 2, 2 }; int[] target1 = { 1, 2 }; int[] nums2 = { 1, 2, 3 }; int[] target2 = { 1 }; Console.WriteLine(Countsubarrays(nums1, target1)); // Output: 4 Console.WriteLine(Countsubarrays(nums2, target2)); // Output: 3 } }
JavaScript function countSubarrays(nums, target) { let count = 0; for (let i = 0; i < nums.length; i++) { for (let j = i; j < nums.length; j++) { if (!target.every(x => nums.slice(i, j + 1).includes(x))) { count += 1; } } } return count; } // Example inputs const nums1 = [1, 2, 2]; const target1 = [1, 2]; const nums2 = [1, 2, 3]; const target2 = [1]; // Outputs console.log(countSubarrays(nums1, target1)); // Output: 4 console.log(countSubarrays(nums2, target2)); // Output: 3
Time Complexity: O(n^3) where n is the length of the input array.
Space Complexity: O(1)
Similar Reads
Count of Subarrays in an array containing numbers from 1 to the length of subarray Given an array arr[] of length N containing all elements from 1 to N, the task is to find the number of sub-arrays that contain numbers from 1 to M, where M is the length of the sub-array. Examples: Input: arr[] = {4, 1, 3, 2, 5, 6} Output: 5 Explanation: Desired Sub-arrays = { {4, 1, 3, 2}, {1}, {1
7 min read
Count subarrays containing at least K zero Given an array arr[] of N integers and a positive value K, the task is to find the number of subarrays of the given array that contains at least K zero. Examples: Input: N = 5, arr = [1, 3, 0, 0, 4], K =1 Output: 14Explanation: All subarrays containing at least 1 negative element are as follows: [1,
7 min read
Find sum of count of duplicate numbers in all subarrays of given array Given an array arr[] of size N. The task it to find the sum of count of duplicate numbers in all subarrays of given array arr[]. For example array {1, 2, 3, 2, 3, 2} has two duplicate elements (i.e, 2 and 3 come more than one time in the array). Examples:Input: N = 2, arr = {3,3}Output: 1Explanation
6 min read
Count subarrays consisting of only 0's and only 1's in a binary array Given a binary array consisting of only zeroes and ones. The task is to find: The number of subarrays which has only 1 in it.The number of subarrays which has only 0 in it.Examples: Input: arr[] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1} Output: The number of subarrays consisting of 0 only: 7 The number
14 min read
Count of elements which is the sum of a subarray of the given Array Given an array arr[], the task is to count elements in an array such that there exists a subarray whose sum is equal to this element.Note: Length of subarray must be greater than 1. Examples: Input: arr[] = {1, 2, 3, 4, 5, 6, 7} Output: 4 Explanation: There are 4 such elements in array - arr[2] = 3
7 min read