Open In App

Count of Subarrays not containing all elements of another Array

Last Updated : 11 Oct, 2023
Comments
Improve
Suggest changes
Like Article
Like
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)


Next Article

Similar Reads