审查密码测试 - pair_sum_even_count

时间:2011-01-16 00:33:42

标签: java algorithm puzzle

我最近参加了一项关于贪婪的在线测试,作为招聘流程的一部分。我在1小时内得到了两个简单的问题。对于那些不懂鳕鱼的人来说,它是一个在线编码测试网站,你可以用许多不同语言解决ACM风格的问题。

如果您有大约30分钟,请查看此http://codility.com/demo/run/

我选择的武器通常是Java。

所以,我遇到的一个问题如下(我会记住,应该截取屏幕截图)

假设您有数组A [0] = 1 A [1] = - 1 .... A [n] = x

那么找出A [i] + A [j]的平均数的最明智的方法是什么呢? Ĵ

所以,如果我们有{1,2,3,4,5} 我们有1 + 3 1 + 5 2 + 4 3 + 5 = 4对甚至是

我写的代码是一些事情

int sum=0;
for(int i=0;i<A.length-1;i++){
 for (int j=i+1;j<A.length;j++){
   if( ((A[i]+A[j])%2) == 0 && i<j) {
       sum++;
    }
  }
}

还有一个限制,如果对的数量大于1e9那么它应该返回-1,但让我们忘记它。

你能为此提出更好的解决方案吗?在正常情况下,元素的数量不会超过1e9。

我认为上述代码扣除了27分(即它并不完美)。 Codility对出了什么问题给出了详细的评估,我现在还没有。

12 个答案:

答案 0 :(得分:29)

两个整数之和即使且仅当它们都是偶数或两者都是奇数时。您可以简单地浏览阵列并统计平均值和赔率。从一组大小 N 组合k个数字的可能性是 N! /((N - k)!·k!)。您只需要将 N 和2的evens / odds数量设为 k 。为此,上面简化为(N·(N-1))/ 2 i < j所做的所有条件都是指定每个组合只计算一次。

答案 1 :(得分:12)

您可以在不单独计算每一对的情况下找到总和。

如果A [i]为偶数且A [j]为偶数,

A[i]+A[j]甚至;或 A [i]为奇数,A [j]为奇数

可以保留最多为j的奇数和偶数的运行总数,并根据 A [j]是奇数还是偶数添加到总和:

int sum = 0;

int odd = 0;
int even = 0;
for(int j = 0; j < A.length; j++) {
    if(A[j] % 2 == 0) {
        sum += even;
        even++;
    } else {
        sum += odd;
        odd++;
    }
}

修改

如果您查看A={1,2,3,4,5},j的每个值都会添加A[j]作为第二个数字的对数。

Even values:
A[j]=2 - sum += 0
A[j]=4 - sum += 1 - [2+4]

Odd values:
A[j]=1 - sum += 0
A[j]=3 - sum += 1 - [1+3]
A[j]=5 - sum += 2 - [1+5, 3+5]

答案 2 :(得分:5)

请检查

if (A == null || A.length < 2) {
  return 0;
}

int evenNumbersCount = 0;
int oddNumberCount = 0;

for (int aA : A) {
  if (aA % 2 == 0) {
    evenNumbersCount++;
  } else {
    oddNumberCount++;
  }
}

int i = (evenNumbersCount * (evenNumbersCount - 1)) / 2 + (oddNumberCount * (oddNumberCount - 1)) / 2;
return i > 1000000000 ? -1 : i;

如果有人在理解桑特所说的是另一种解释时有问题: 只有奇数+奇数和偶数+偶数给出偶数。你必须找到有多少偶数和奇数。如果你有它想象这是一个会议的问题。在奇数列表和偶数列表中有多少人偏离对。这是同一个问题,因为在聚会上会有多少人对彼此说。这也是完整图形中的边数。答案是n *(n-1)/ 2,因为有n个人,你必须晃动n-1个人的手并除以2,因为另一个人不能将你的摇动视为不同的一个。正如你在这里有两个单独的“派对”,你必须独立计算它们。

答案 3 :(得分:3)

这很简单 首先,您需要在集合中找到赔率甚至数量。 例如。如果x&amp; 1 == 1则x为奇数,即使不是这样, 如果你有这个,知道为每个人增加两个偶数或两个赔率甚至可以得到。 您需要计算偶数和奇数两个元素的组合之和。

有一个A [] = {1,2,3,4,5};

int odds=0, evens=0;
for (int i=0; i< A.length; ++i)
{
if (A[i]&1==1) odds++;
else evens++;
}
return odds*(odds-1)/2 + evens*(evens-1)/2;  

//上面的事实是,从一组大小N中组合k个数字的可能性的数量是N! /((N - k)!·k!)。对于k = 2,这简化为(N·(N-1))/ 2

答案 4 :(得分:1)

也可以看到这个答案

int returnNumOFOddEvenSum(int [] A){
    int sumOdd=0;
    int sumEven=0;

    if(A.length==0)
        return 0;

    for(int i=0; i<A.length; i++)
    {
        if(A[i]%2==0)
            sumEven++;
        else
            sumOdd++;
    }
    return factSum(sumEven)+factSum(sumOdd);
}

int factSum(int num){
    int sum=0;
    for(int i=1; i<=num-1; i++)
    {
        sum+=i;
    }
    return sum;
}

答案 5 :(得分:1)

public int getEvenSumPairs(int[] array){

    int even=0;
    int odd=0;
    int evenSum=0;

     for(int j=0; j<array.length; ++j){

           if(array[j]%2==0) even++;
           else odd++;
     }
     evenSum=((even*(even-1)/2) + (odd *(odd-1)/2) ;
     return evenSum;
}

答案 6 :(得分:0)

基于“Svante”答案的Java实现很有效:

int getNumSumsOfTwoEven(int[] a) {

    long numOdd = 0;
    long numEven = 0;
    for(int i = 0; i < a.length; i++) {
        if(a[i] % 2 == 0) { //even
            numOdd++;
        } else {
            numEven++;
        }
    }

    //N! / ((N - k)! · k!), where N = num. even nums or num odd nums, k = 2
    long numSumOfTwoEven = (long)(fact(numOdd) / (fact(numOdd - 2) * 2));
    numSumOfTwoEven += (long)(fact(numEven) / (fact(numEven - 2) * 2));

    if(numSumOfTwoEven > ((long)1e9)) {
        return -1;
    }
    return numSumOfTwoEven;

}
// This is a recursive function to calculate factorials
long fact(int i) {
    if(i == 0) {
        return 1;
    }
    return i * fact(i-1);
}

答案 7 :(得分:0)

算法很无聊,这是一个python解决方案。

>>> A = range(5)
>>> A
[0, 1, 2, 3, 4]
>>> even = lambda n: n % 2 == 0
>>> [(i, j) for i in A for j in A[i+1:] if even(i+j)]
[(0, 2), (0, 4), (1, 3), (2, 4)]

我将使用vim尝试另一种解决方案。

答案 8 :(得分:0)

您可以删除if / else语句,只需拥有以下内容:

int pair_sum_v2( int A[], int N ) {
int totals[2] = { 0, 0 };

for (int i = 0; i < N; i++ ) {
    totals[ A[i] & 0x01 ]++;
    }

return ( totals[0] * (totals[0]-1) + totals[1] * (totals[1]-1) ) / 2;
}

答案 9 :(得分:0)

将奇数计为 n1 ,并将偶数计为 n2

Pair(x,y)的总和是偶数,只有当我们从偶数组或xy中同时选择xy时奇数集(从偶数集中选择x,从奇数集中选择y,反之亦然,总是会导致对的总和为奇数。)

总组合使得每对的总和均为= n1C2 + n2C2

= (n1!) / ((n1-2)! * 2!) + (n2!) / ((n2-2)! * 2!)  
= (n1 * (n1 - 1)) / 2 + (n2 * (n2 - 1)) / 2 

---等式1.
例如:让数组如下:{1,2,3,4,5}
偶数= _ em> n1 = 2
奇数的数量= n2 = 2

总对,使得该对的和甚至来自等式:1 = (2*1)/2 + (3*2)/2 = 4 并且对是:(1,3), (1,5), (2,4), (3,5)
采用传统的方法进行添加然后检查可能会导致编程中的正整数和负极值都出现整数溢出。

答案 10 :(得分:0)

这是一些pythonic解决方案

x = [1,3,56,4,3,2,0,6,78,90]

def solution(x):
    sumadjacent = [x[i]+x[i+1] for i in range(len(x)-1) if x[i] < x[i+1]]
    evenpairslist = [ True for j in sumadjacent if j%2==0]
    return evenpairslist

if __name__=="__main__":
    result=solution(x)
    print(len(result))

答案 11 :(得分:-1)

    int total = 0;
    int size = A.length;
    for(int i=0; i < size; i++) {
        total += (A[size-1] - A[i]) / 2;
    }
    System.out.println("Total : " + total);