📌  相关文章
📜  计算具有相同偶数和奇数元素的子数组

📅  最后修改于: 2021-10-27 08:37:07             🧑  作者: Mango

给定一个由 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^2)  时间。
一个高效的方法在 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 现场工作专业课程学生竞争性编程现场课程