简体   繁体   English

面试-在数组中找到偶数和对

[英]Interview - finding even sum pair in an array

Given an array , how would you return the number of pairs which sum to an even number? 给定一个数组,您将如何返回总和为偶数的对数?

For example: 例如:

a[] = { 2 , -6 , 1, 3, 5 }

In this array , the nos which pair to an even sum are (2,-6), (1,3) , (1,5), (3,5) 在此数组中,与偶数和成对的no是(2,-6),(1,3),(1,5),(3,5)

Function should return 4 as there are 4 pairs or -1 if none. 函数应该返回4,因为有4对,如果没有对则返回-1。

Expected time complexity - O(N) worst case Expected space complexity - O(N) worst case 预期时间复杂度-O(N)最坏情况预期空间复杂度-O(N)最坏情况

Approach 1: Brute force 方法1:蛮力

Start with the first number
  Start with second number
      assign the sum to a temp variable
      check if the temp is even
          If it is increment evenPair count
      else
          increment the second index

Here the time complexity is O(N2) 这里的时间复杂度为O(N2)

int odd = 0, even = 0;
for (int i = 0; i < n; i++) {
    if (a[i] % 2 == 0) {
        even++;
    } else {
        odd++;
    }
}
int answer = (odd * (odd - 1) + even * (even - 1)) / 2;

If to use standard algorithms then the code can look the following way 如果使用标准算法,则代码可以如下所示

#include <iostream>
#include <utility>
#include <numeric>
#include <iterator>

int main() 
{
    int a[] = { 2 , -6 , 1, 3, 5 };

    typedef size_t Odd, Even;
    auto p = std::accumulate( std::begin( a ), std::end( a ), 
                              std::pair<Odd, Even>( 0, 0 ),
                              []( std::pair<Odd, Even> &acc, int x )
                              {
                                return x & 1 ? ++acc.first : ++acc.second, acc;
                              } );

    std::cout << "There are " 
              << ( p.first * ( p.first - 1 ) + p.second * ( p.second - 1 ) ) / 2
              << " even sums" << std::endl;

    return 0;
}

The output is 输出是

There are 4 even sums

Take into account that n! / ( 2! * ( n - 2 )! ) 考虑到n! / ( 2! * ( n - 2 )! ) n! / ( 2! * ( n - 2 )! ) is equivalent to ( n - 1 ) * n / 2 n! / ( 2! * ( n - 2 )! )等于( n - 1 ) * n / 2

The advantage of using the standard algorithm is that you can use any subrange of a sequence. 使用标准算法的优点是可以使用序列的任何子范围。 Also you can use a standard stream input because std::accumulate uses input iterator. 您也可以使用标准流输入,因为std::accumulate使用输入迭代器。

Also it would be much better if in the description of the assignment there would be written that the function should return 0 instead of -1 if there is no even sums among elements of an array. 如果在赋值的描述中写成如果数组元素之间没有偶数和,则函数应返回0而不是-1,那会更好。

It is not shameful to show this code in an interview though I advice never do any assignments in an interview. 尽管我建议不要在面试中做任何作业,但在面试中显示此代码并不可耻。 Interview is not an exam. 面试不是考试。

If a and b are even, a + b is even. 如果a和b是偶数,则a + b是偶数。
If they're odd, a + b is also even. 如果它们是奇数,则a + b也是偶数。
If one is odd and one is even, a + b is odd. 如果一个是奇数,一个是偶数,则a + b是奇数。

This means that we don't need to perform any additions, we only need to know how many numbers there are of each kind. 这意味着我们不需要执行任何加法运算,我们只需要知道每种数字有多少个即可。
Finding this out takes linear time. 找出这一点需要花费线性时间。

If you have k numbers, there are k - 1 pairs that include the first number, k - 2 involving the second, and so on. 如果您有k个数字,则有k-1对包含第一个数字,k-2对包含第二个数字,依此类推。
Using the familiar summation formula, sum(1 .. n) = (n * (n + 1)) / 2 , 使用熟悉的求和公式sum(1 .. n) = (n * (n + 1)) / 2

let

ne = number of even numbers
no = number of odd numbers

then, 然后,

number of pairs = (ne-1) * ne / 2 + (no-1) * no / 2 
                = ((ne-1)*ne + (no-1)*no) / 2

That computation runs in constant time, so the time complexity is still linear. 该计算以恒定的时间运行,因此时间复杂度仍然是线性的。

And we only need a constant amount of extra space, which is better than the requirements. 而且我们只需要恒定数量的额外空间,这比需求要好。


Possible followup interview questions possibly worth thinking about: 可能的后续采访问题可能值得考虑:

What happens to the complexities (both in time and space) if: 如果发生以下情况,复杂性(在时间和空间上)会发生什么:

  • duplicates are only counted once, ie {1,1,1,2} only has two such pairs? 重复项仅计算一次,即{1,1,1,2}仅具有两个这样的对?
  • we disregard order, ie (1,2) and (2,1) are the "same" pair? 我们忽略顺序,即(1,2)(2,1)是“相同”对吗?

A different approach would be compute the number of sums by even and odds, and then sum then together 一种不同的方法是按奇数和偶数计算和的数量,然后求和然后加在一起

int sumO = 0 , sumE = 0 , numO = 0 , numE = 0;
for (int i=0; i < 5; i++)
{
    if (a[i] % 2 == 0)
    {
        sumE += numE;
        numE ++;
    }
    else
    {
        sumO += numO;
        numO ++;
    }
}

printf ("Total: %d\n", sumO + sumE);

I got this question from an interview. 我从一次采访中得到了这个问题。 No need to total even and odd both separate. 无需将偶数和奇数全部分开。

public static int evenTotalPairs(int[] A) {
int size = A.length;
int evens = 0;
for(int i = 0; i < size; i++ ){
    if(A[i] % 2 == 0){
        evens++;
    }
}
return evens*(evens-1)/2 + (size-evens)*(size-evens-1)/2;

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM