Recuento de subarreglos que no contienen todos los elementos de otro arreglo

Dadas dos arrays nums[] de tamaño N y target[] . La tarea es encontrar el número de subarreglos no vacíos de nums[] que no contienen todos los números en target[] . Como la respuesta puede ser muy grande, calcule el resultado módulo 10 9 +7 .

Ejemplos:

Entrada: nums = {1, 2, 2}, objetivo = {1, 2}
Salida: 4
Explicación:  Los subarreglos que no contienen ni 1 ni 2 en nums[] son: 
{1}, {2}, { 2}, {2, 2}

Entrada: nums = {1, 2, 3}, target = {1}
Salida: 3
Explicación: Los subarreglos son {2}, {3}, {2, 3}.

 

Enfoque: El enfoque simple para resolver este problema se basa en la siguiente idea: 

  • Encuentre el número de subarreglos que contienen todos los elementos del arreglo target[] .
  • Si hay X tales subarreglos, entonces el número de subarreglos que no contienen todos los elementos será [N*(N+1)/2 – X], donde N*(N+1)/2 es el número total de subarreglos de array números[] .
  • Aquí use el concepto de dos punteros para encontrar el número X y obtener el resultado deseado usando la fórmula anterior.

Siga los pasos que se mencionan a continuación:

  • Mantenga todos los números en un conjunto desordenado y mantenga el conteo de frecuencia de todos estos números en un mapa .
  • Ahora use el enfoque de dos punteros con un puntero izquierdo y uno derecho .
    • Avance el extremo derecho hasta que todos los números del objetivo se encuentren en esa ventana.
    • Una vez que lo hagamos, cuente cuántos subarreglos comienzan a la izquierda que contienen cada número en el objetivo y avancen a la izquierda hasta que ya no haya todos los elementos del objetivo[] .
  • Siga restando el subarreglo que contiene cada número en el objetivo del subarreglo total, lo que dará la respuesta final requerida.

A continuación se muestra la implementación del enfoque anterior.

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>
Producción

4

Tiempo Complejidad:  O(N)
Espacio Auxiliar: O(N)

Publicación traducida automáticamente

Artículo escrito por rohit768 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *