Open In App

Count of Subarrays not containing all elements of another Array

Improve
Improve
Like Article
Like
Save
Share
Report

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:

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

                    

Output
4
3







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



Last Updated : 11 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads