Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Count of Subarrays not containing all elements of another Array

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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>


Output

4

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

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


Output

4
3

Time Complexity: O(n^3) where n is the length of the input array.
Space Complexity: O(1)


My Personal Notes arrow_drop_up
Last Updated : 10 May, 2023
Like Article
Save Article
Similar Reads
Related Tutorials