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++ 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 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 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# 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. |
<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:
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.
#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;
} |
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
}
} |
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
|
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
}
} |
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)