Count of Subarrays not containing all elements of another Array
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++
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
int countSubarrays(vector< int >& nums,
vector< int >& target)
{
int N = nums.size();
long long ans = N * (N + 1LL) / 2;
unordered_map< int , int > freq;
unordered_set< int > active(target.begin(),
target.end());
int left = 0;
for ( int right = 0; right < N; right++)
{
if (active.count(nums[right]))
freq[nums[right]]++;
while (freq.size() == target.size()) {
ans -= (N - right);
if (active.count(nums[left])) {
if (--freq[nums[left]] == 0)
freq.erase(nums[left]);
}
left++;
}
}
return ans % MOD;
}
int main()
{
vector< int > nums = { 1, 2, 2 };
vector< int > target = { 1, 2 };
cout << countSubarrays(nums, target);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int MOD = 1000000007 ;
static int countSubarrays(Integer[]nums,
Integer[] target)
{
int N = nums.length;
long ans = N * (N + 1 ) / 2 ;
HashMap<Integer,Integer> freq = new HashMap<Integer,Integer> ();
HashSet<Integer> active = new HashSet<Integer>();
active.addAll(Arrays.asList(target));
int left = 0 ;
for ( int right = 0 ; right < N; right++)
{
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 );
}
while (freq.size() == target.length) {
ans -= (N - right);
if (active.contains(nums[left])) {
if (freq.get(nums[left])- 1 == 0 )
freq.remove(nums[left]);
}
left++;
}
}
return ( int ) (ans % MOD);
}
public static void main(String[] args)
{
Integer[] nums = { 1 , 2 , 2 };
Integer[] target = { 1 , 2 };
System.out.print(countSubarrays(nums, target));
}
}
|
Python3
MOD = 1000000007
def countSubarrays(nums, target) :
N = len (nums)
ans = N * (N + 1 ) / / 2
freq = {}
active = set (target)
left = 0
for right in range ( 0 , N) :
if ( nums[right] in active) :
freq[nums[right]] = freq[nums[right]] + 1 if nums[right] in freq else 1
while ( len (freq) = = len (target)) :
ans - = (N - right)
if ( nums[left] in active) :
if ( nums[left] in freq ) :
if freq[nums[left]] = = 1 :
del freq[nums[left]]
else :
freq[nums[left]] - = 1
left + = 1
return ans % MOD
if __name__ = = "__main__" :
nums = [ 1 , 2 , 2 ]
target = [ 1 , 2 ]
print (countSubarrays(nums, target))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public static int MOD = 1000000007;
public static int countSubarrays(List< int > nums, List< int > target)
{
int N = nums.Count;
long ans = (( long )N * ( long )(N + 1))/2;
Dictionary< int , int > freq = new Dictionary< int , int >();
HashSet< int > active = new HashSet< int >(target);
int left = 0;
for ( int right = 0; right < N; right++)
{
if (active.Contains(nums[right])){
int val;
if (freq.TryGetValue(nums[right], out val))
{
freq[nums[right]] = val + 1;
}
else
{
freq.Add(nums[right], 1);
}
}
while (freq.Count == target.Count) {
ans -= (N - right);
if (active.Contains(nums[left])) {
--freq[nums[left]];
if (freq[nums[left]] == 0){
freq.Remove(nums[left]);
}
}
left++;
}
}
return ( int )(ans % MOD);
}
public static void Main( string [] args)
{
List< int > nums = new List< int >{
1, 2, 2
};
List< int > target = new List< int >{
1, 2
};
Console.Write(countSubarrays(nums, target));
}
}
|
Javascript
<script>
const MOD = 1000000007
function countSubarrays(nums, target){
let N = nums.length
let ans =Math.floor(N * (N + 1) / 2)
let freq = new Map()
let active = new Set()
for (let i of target){
active.add(i)
}
let left = 0
for (let right=0;right<N;right++){
if (active.has(nums[right])){
freq.set(nums[right], freq.has(nums[right])?freq[nums[right]] + 1:1)
}
while (freq.size == target.length){
ans -= (N - right)
if (active.has(nums[left])){
if (freq.has(nums[left])){
if (freq.get(nums[left]) == 1)
freq. delete (nums[left])
else
freq.set(nums[left], freq.get(nums[left])- 1)
}
}
left += 1
}
}
return ans % MOD
}
let nums = [ 1, 2, 2 ]
let target = [ 1, 2 ]
document.write(countSubarrays(nums, target), "</br>" )
<script>
|
Time Complexity:
Auxiliary Space:
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;
cout << countSubarrays(nums2, target2) << endl;
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));
System.out.println(countSubarrays(nums2, target2));
}
}
|
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
nums1 = [ 1 , 2 , 2 ]
target1 = [ 1 , 2 ]
nums2 = [ 1 , 2 , 3 ]
target2 = [ 1 ]
print (count_subarrays(nums1, target1))
print (count_subarrays(nums2, target2))
|
C#
using System;
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 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));
Console.WriteLine(Countsubarrays(nums2, target2));
}
}
|
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;
}
const nums1 = [1, 2, 2];
const target1 = [1, 2];
const nums2 = [1, 2, 3];
const target2 = [1];
console.log(countSubarrays(nums1, target1));
console.log(countSubarrays(nums2, target2));
|
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
Share your thoughts in the comments
Please Login to comment...