给定一个由 N 个整数组成的数组,计算奇偶子数组的数量。偶数-奇数子数组是包含相同数量的偶数和奇数整数的子数组。
例子 :
Input : arr[] = {2, 5, 7, 8}
Output : 3
Explanation : There are total 3 even-odd subarrays.
1) {2, 5}
2) {7, 8}
3) {2, 5, 7, 8}
Input : arr[] = {3, 4, 6, 8, 1, 10}
Output : 3
Explanation : In this case, 3 even-odd subarrays are:
1) {3, 4}
2) {8, 1}
3) {1, 10}
这个问题主要是具有相同数量的 0 和 1 的计数子阵列的变体。
一种天真的方法是使用两个循环检查所有可能的子数组,无论它们是否是奇偶子数组。这种方法将采取时间。
一个高效的方法在 O(N) 时间内解决了这个问题,它基于以下思想:
- 奇偶子数组的长度总是偶数。
- 跟踪偶数和奇数的频率之间的差异。
- 这种频率差异的散列对于查找奇偶子数组的数量很有用。
其基本思想是利用奇偶数出现的频率之差来求得最优解。我们将为差值的正负值维护两个整数哈希数组。
-> 以更好的方式理解示例:
-> 考虑差异 = freq(odd) – freq(even)
-> 要计算此差异,请在存在时增加 ‘difference’ 的值
奇数,当有偶数时递减。 (最初,差异 = 0)
arr[] = {3, 4, 6, 8, 1, 10}
索引 0 1 2 3 4 5 6
阵列 3 4 6 8 1 10
差 0 1 0 -1 -2 -1 -2
-> 观察,每当值 ‘k’ 在 ‘difference’ 数组中重复时,就存在一个
该值的每个先前出现的奇偶子数组,即子数组存在于
索引 i + 1 到 j,其中差异 [i] = k 和差异 [j] = k。
-> 值 ‘0’ 在索引 2 的 ‘difference’ 数组中重复,因此子数组存在于
(0, 2] 索引。类似地,对于重复值 ‘-1’(在索引 3 和 5)和 ‘-2’(在
索引 4 和 6),子数组存在于 (3, 5] 和 (4, 6] 索引)。
下面是上述O(N)解决方案的实现。
C++
/*C++ program to find total number of
even-odd subarrays present in given array*/
#include
using namespace std;
// function that returns the count of subarrays that
// contain equal number of odd as well as even numbers
int countSubarrays(int arr[], int n)
{
// initialize difference and answer with 0
int difference = 0;
int ans = 0;
// create two auxiliary hash arrays to count frequency
// of difference, one array for non-negative difference
// and other array for negative difference. Size of these
// two auxiliary arrays is 'n+1' because difference can
// reach maximum value 'n' as well as minimum value '-n'
int hash_positive[n + 1], hash_negative[n + 1];
// initialize these auxiliary arrays with 0
fill_n(hash_positive, n + 1, 0);
fill_n(hash_negative, n + 1, 0);
// since the difference is initially 0, we have to
// initialize hash_positive[0] with 1
hash_positive[0] = 1;
// for loop to iterate through whole
// array (zero-based indexing is used)
for (int i = 0; i < n ; i++)
{
// incrementing or decrementing difference based on
// arr[i] being even or odd, check if arr[i] is odd
if (arr[i] & 1 == 1)
difference++;
else
difference--;
// adding hash value of 'difference' to our answer
// as all the previous occurrences of the same
// difference value will make even-odd subarray
// ending at index 'i'. After that, we will increment
// hash array for that 'difference' value for
// its occurrence at index 'i'. if difference is
// negative then use hash_negative
if (difference < 0)
{
ans += hash_negative[-difference];
hash_negative[-difference]++;
}
// else use hash_positive
else
{
ans += hash_positive[difference];
hash_positive[difference]++;
}
}
// return total number of even-odd subarrays
return ans;
}
// Driver code
int main()
{
int arr[] = {3, 4, 6, 8, 1, 10, 5, 7};
int n = sizeof(arr) / sizeof(arr[0]);
// Printing total number of even-odd subarrays
cout << "Total Number of Even-Odd subarrays"
" are " << countSubarrays(arr,n);
return 0;
}
Java
//Java program to find total
// number of even-odd subarrays
// present in given array
class GFG {
// function that returns the
// count of subarrays that
// contain equal number of
// odd as well as even numbers
static int countSubarrays(int[] arr,
int n) {
// initialize difference
// and answer with 0
int difference = 0;
int ans = 0;
// create two auxiliary hash
// arrays to count frequency
// of difference, one array
// for non-negative difference
// and other array for negative
// difference. Size of these
// two auxiliary arrays is 'n+1'
// because difference can
// reach maximum value 'n' as
// well as minimum value '-n'
// initialize these
// auxiliary arrays with 0
int[] hash_positive = new int[n + 1];
int[] hash_negative = new int[n + 1];
// since the difference is
// initially 0, we have to
// initialize hash_positive[0] with 1
hash_positive[0] = 1;
// for loop to iterate
// through whole array
// (zero-based indexing is used)
for (int i = 0; i < n; i++) {
// incrementing or decrementing
// difference based on
// arr[i] being even or odd,
// check if arr[i] is odd
if ((arr[i] & 1) == 1) {
difference++;
} else {
difference--;
}
// adding hash value of 'difference'
// to our answer as all the previous
// occurrences of the same difference
// value will make even-odd subarray
// ending at index 'i'. After that,
// we will increment hash array for
// that 'difference' value for its
// occurrence at index 'i'. if
// difference is negative then use
// hash_negative
if (difference < 0) {
ans += hash_negative[-difference];
hash_negative[-difference]++;
} // else use hash_positive
else {
ans += hash_positive[difference];
hash_positive[difference]++;
}
}
// return total number
// of even-odd subarrays
return ans;
}
// Driver code
public static void main(String[] args) {
int[] arr = new int[]{3, 4, 6, 8,
1, 10, 5, 7};
int n = arr.length;
// Printing total number
// of even-odd subarrays
System.out.println("Total Number of Even-Odd"
+ " subarrays are "
+ countSubarrays(arr, n));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to find total
# number of even-odd subarrays
# present in given array
# function that returns the count
# of subarrays that contain equal
# number of odd as well as even numbers
def countSubarrays(arr, n):
# initialize difference and
# answer with 0
difference = 0
ans = 0
# create two auxiliary hash
# arrays to count frequency
# of difference, one array
# for non-negative difference
# and other array for negative
# difference. Size of these two
# auxiliary arrays is 'n+1'
# because difference can reach
# maximum value 'n' as well as
# minimum value '-n'
hash_positive = [0] * (n + 1)
hash_negative = [0] * (n + 1)
# since the difference is
# initially 0, we have to
# initialize hash_positive[0] with 1
hash_positive[0] = 1
# for loop to iterate through
# whole array (zero-based
# indexing is used)
for i in range(n):
# incrementing or decrementing
# difference based on arr[i]
# being even or odd, check if
# arr[i] is odd
if (arr[i] & 1 == 1):
difference = difference + 1
else:
difference = difference - 1
# adding hash value of 'difference'
# to our answer as all the previous
# occurrences of the same difference
# value will make even-odd subarray
# ending at index 'i'. After that,
# we will increment hash array for
# that 'difference' value for
# its occurrence at index 'i'. if
# difference is negative then use
# hash_negative
if (difference < 0):
ans += hash_negative[-difference]
hash_negative[-difference] = hash_negative[-difference] + 1
# else use hash_positive
else:
ans += hash_positive[difference]
hash_positive[difference] = hash_positive[difference] + 1
# return total number of
# even-odd subarrays
return ans
# Driver code
arr = [3, 4, 6, 8, 1, 10, 5, 7]
n = len(arr)
# Printing total number
# of even-odd subarrays
print("Total Number of Even-Odd subarrays are " +
str(countSubarrays(arr, n)))
# This code is contributed
# by Yatin Gupta
C#
// C# program to find total
// number of even-odd subarrays
// present in given array
using System;
class GFG
{
// function that returns the
// count of subarrays that
// contain equal number of
// odd as well as even numbers
static int countSubarrays(int []arr,
int n)
{
// initialize difference
// and answer with 0
int difference = 0;
int ans = 0;
// create two auxiliary hash
// arrays to count frequency
// of difference, one array
// for non-negative difference
// and other array for negative
// difference. Size of these
// two auxiliary arrays is 'n+1'
// because difference can
// reach maximum value 'n' as
// well as minimum value '-n'
int []hash_positive = new int[n + 1];
int []hash_negative = new int[n + 1];
// initialize these
// auxiliary arrays with 0
Array.Clear(hash_positive, 0, n + 1);
Array.Clear(hash_negative, 0, n + 1);
// since the difference is
// initially 0, we have to
// initialize hash_positive[0] with 1
hash_positive[0] = 1;
// for loop to iterate
// through whole array
// (zero-based indexing is used)
for (int i = 0; i < n ; i++)
{
// incrementing or decrementing
// difference based on
// arr[i] being even or odd,
// check if arr[i] is odd
if ((arr[i] & 1) == 1)
difference++;
else
difference--;
// adding hash value of 'difference'
// to our answer as all the previous
// occurrences of the same difference
// value will make even-odd subarray
// ending at index 'i'. After that,
// we will increment hash array for
// that 'difference' value for its
// occurrence at index 'i'. if
// difference is negative then use
// hash_negative
if (difference < 0)
{
ans += hash_negative[-difference];
hash_negative[-difference]++;
}
// else use hash_positive
else
{
ans += hash_positive[difference];
hash_positive[difference]++;
}
}
// return total number
// of even-odd subarrays
return ans;
}
// Driver code
static void Main()
{
int []arr = new int[]{3, 4, 6, 8,
1, 10, 5, 7};
int n = arr.Length;
// Printing total number
// of even-odd subarrays
Console.Write("Total Number of Even-Odd" +
" subarrays are " +
countSubarrays(arr,n));
}
}
// This code is contributed by
// Manish Shaw(manishshaw1)
PHP
Javascript
Total Number of Even-Odd subarrays are 7
时间复杂度: O(N),其中 N 是整数的数量。
辅助空间: O(2N),其中 N 是整数的数量。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。