Skip to content
Related Articles

Related Articles

Count of Subarrays not containing all elements of another Array

View Discussion
Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 30 May, 2022
View Discussion
Improve Article
Save 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)

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!