📌  相关文章
📜  不包含另一个数组的所有元素的子数组计数

📅  最后修改于: 2022-05-13 01:56:14.931000             🧑  作者: Mango

不包含另一个数组的所有元素的子数组计数

给定两个大小为N的数组nums[]target[] 。任务是找到不包含target[]中每个数字的nums[]的非空子数组的数量。由于答案可能非常大,请以10 9 +7为模计算结果。

例子:

方法:解决此问题的简单方法基于以下想法:

请按照以下步骤操作:

  • 将所有数字保持在无序集中,并将所有这些数字的频率计数保持在地图中。
  • 现在使用带有指针和指针的两指针方法。
    • 推进右端点,直到在该窗口中找到目标中的每个数字。
    • 一旦我们这样做了,计算有多少子数组从左边开始,包含 target 中的每个数字,然后向左前进,直到不再有target[]的所有元素。
  • 继续从总子数组中减去包含目标中每个数字的子数组,这将产生最终所需的答案。

下面是上述方法的实现。

C++
// C++ code to implement the approach
 
#include 
using namespace std;
 
const int MOD = 1000000007;
 
// Function to count subarrays that
// do not contain target array
int countSubarrays(vector& nums,
                   vector& 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 freq;
    unordered_set 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 nums = { 1, 2, 2 };
    vector 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 freq = new HashMap ();
    HashSet active = new HashSet();
    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



输出
4

时间复杂度: O(N)
辅助空间: O(N)