Reputation: 321
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)
Function should return 4 as there are 4 pairs or -1 if none.
Expected time complexity - O(N) worst case Expected space complexity - O(N) worst case
Approach 1: Brute force
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)
Upvotes: 1
Views: 6446
Reputation: 31
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;
}
Upvotes: 0
Reputation: 311186
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 )! )
is equivalent to ( 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.
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.
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.
Upvotes: 2
Reputation: 7552
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);
Upvotes: 0
Reputation: 66459
If a and b are even, a + b is even.
If they're odd, a + b is also even.
If one is odd and one is even, a + b is odd.
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.
Using the familiar summation formula, 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:
{1,1,1,2}
only has two such pairs?(1,2)
and (2,1)
are the "same" pair?Upvotes: 2
Reputation: 448
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;
Upvotes: 8