不包含另一个数组的所有元素的子数组计数
给定两个大小为N的数组nums[]和target[] 。任务是找到不包含target[]中每个数字的nums[]的非空子数组的数量。由于答案可能非常大,请以10 9 +7为模计算结果。
例子:
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}.
方法:解决此问题的简单方法基于以下想法:
- 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.
请按照以下步骤操作:
- 将所有数字保持在无序集中,并将所有这些数字的频率计数保持在地图中。
- 现在使用带有左指针和右指针的两指针方法。
- 推进右端点,直到在该窗口中找到目标中的每个数字。
- 一旦我们这样做了,计算有多少子数组从左边开始,包含 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
时间复杂度:
辅助空间: