Обзор теста на кодовость - pair_sum_even_count

Недавно я проверил онлайн-тест на кодовость как часть процесса найма. Я получил две простые проблемы, которые нужно решить за 1 час. Для тех, кто не знает кодовости, это сайт онлайн-кодирования, где вы можете решать проблемы стиля ACM на разных языках.

Если у вас 30 минут, проверьте этот http://codility.com/demo/run/

Моим оружием выбора обычно является Java.

Итак, одна из проблем, которые у меня есть, следующая (я постараюсь запомнить, должен был сделать снимок экрана)

Допустим, у вас есть массив A [0] = 1 A [1] = - 1.... A [n] = x

Тогда какой был бы самый умный способ узнать количество раз, когда A [i] + A [j] будет даже там, где я < 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++;
    }
  }
}

Было еще одно ограничение: если число пар больше, чем 1е9, то оно должно извлекать -1, но позволяет забыть его.

Можете ли вы предложить лучшее решение для этого. Число элементов не будет превышать 1е9 в обычных случаях.

Думаю, я получил 27 очков за вышеупомянутый код (т.е. он не идеален). Codility дает подробную оценку того, что пошло не так, у меня сейчас нет этого.

Ответ 1

Сумма двух целых чисел даже тогда и только тогда, когда они либо четные, либо оба нечетные. Вы можете просто пройти через массив и подсчитать коэффициенты и коэффициенты. Количество возможностей комбинировать k чисел из набора размеров N равно N!/((N - k)! & Middot; k!). Вам просто нужно указать количество коэффициентов evens/odds как N и 2 как k. Для этого выше упрощается (N & middot; (N - 1))/2. Все условие i < j заключается в том, чтобы указать, что каждая комбинация считается только один раз.

Ответ 2

Вы можете найти сумму, не вычисляя каждую пару отдельно.

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++;
    }
}

Edit:

Если вы посмотрите на 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]

Ответ 3

Пожалуйста, проверьте это

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, потому что другой человек не может считать ваше трясти как отличное. Поскольку у вас здесь две отдельные "партии", вы должны рассчитывать их самостоятельно.

Ответ 4

Это очень просто Сначала вам нужно найти количество шансов и даже количество в коллекции. например. x нечетно, если x & 1 == 1, даже в противном случае, если у вас есть это, зная, что добавление двух четных или двух коэффициентов к каждому вы получите даже. Вам нужно вычислить сумму комбинаций двух элементов из четных чисел и нечетных чисел.

с int 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;  

//Выше следует, что число возможностей комбинирования k чисел из набора размеров N равно N!/((N - k)! K). При k = 2 это упрощается до (N · (N - 1))/2

Ответ 5

См. также этот ответ

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;
}

Ответ 6

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;
}

Ответ 7

Реализация Java, которая отлично работает на основе ответа от Svante:

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);
}

Ответ 8

Алгоритмы скучны, вот решение 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.

Ответ 9

Вы можете избавиться от инструкции 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;
}

Ответ 10

Позвольте считать нечетные числа как n1 и считать четные числа как n2.

Сумма Pair(x,y) четна, только если мы выберем как x, так и y из набора четных чисел или обоих x и y из нечетного множества (выбор 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}
число четных чисел = n1 = 2
число нечетных чисел = n2 = 2

Общая пара такая, что пара суммируется даже из уравнения: 1 = (2*1)/2 + (3*2)/2 = 4 и пары: (1,3), (1,5), (2,4), (3,5).
Переход от традиционного подхода к добавлению и проверке может привести к переполнению целых чисел при программировании как с положительными, так и с негативными экстремальными значениями.

Ответ 11

    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);