Обзор теста на кодовость - 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);