最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - Codility "PermMissingElem" Solution in Javascript - Stack Overflow

programmeradmin1浏览0评论

A codility problem asks to find the missing number in zero-indexed array A consisting of N different integers.

E.g.

  Arr[0] = 2
  Arr[1] = 3
  Arr[2] = 1
  Arr[3] = 4
  Arr[4] = 6

I previously submitted a solution that first sorts the array and then performs a forEach function returning the value +1 where the array difference between elements is more than 1, however this doesn't get the 100 points.

Is there a way to improve this?

A codility problem asks to find the missing number in zero-indexed array A consisting of N different integers.

E.g.

  Arr[0] = 2
  Arr[1] = 3
  Arr[2] = 1
  Arr[3] = 4
  Arr[4] = 6

I previously submitted a solution that first sorts the array and then performs a forEach function returning the value +1 where the array difference between elements is more than 1, however this doesn't get the 100 points.

Is there a way to improve this?

Share Improve this question asked Oct 7, 2015 at 3:20 Jose RomeroJose Romero 1171 silver badge4 bronze badges
Add a comment  | 

14 Answers 14

Reset to default 7

Here is 100% javascript solution:

function solution(A) {
    if (!A.length) return 1;
    let n = A.length + 1;
    return (n + (n * n - n) / 2) - A.reduce((a, b) => a + b);
}

We return 1 if the given array is empty, which is the missing element in an empty array.

Next we calculate the 'ordinary' series sum, assuming the first element in the series is always 1. Then we find the difference between the given array and the full series, and return it. This is the missing element.

The mathematical function I used here are series sum, and last element:

  • Sn = (n/2)*(a1 + an)
  • an = a1 + (n - 1)*d

Get 100 in correctness and performance using this function

function solution(A) {
    // write your code in JavaScript (Node.js 4.0.0)
    var size = A.length;
    var sum = (size + 1) * (size + 2) / 2;
    for (i = 0; i < size; i++) {
        sum -= A[i];
    }
    return sum;
}

Easy if you use the Gauss formula to calculate the sum of the first N consecutive numbers:


    function solution(A) {
        var np1, perfectSum, sum;

        if (!A || A.length == 0) {
            return 1;
        }

        np1 = A.length + 1;

        // Gauss formula
        perfectSum = np1 * (1 + np1) / 2;

        // Sum the numbers we have
        sum = A.reduce((prev, current) => prev + current);

        return perfectSum - sum;
    }

From the sum of first natural numbers formula we have

now since the N item for us in the task is (N+1) we substitue n with n+1 and we get

with the formula above we can calculate the sum of numbers from 1 to n+1, since in between these numbers there is the missing number, now what we can do is we can start iterating through the given array A and subtracting the array item from the sum of numbers. The ending sum is the item which was missing in the array. hence:

function solution(A) {

    var n = A.length;

    // using formula of first natural numbers 
    var sum = (n + 1) * (n + 2) / 2;

    for (var i = 0; i < n; i++) {
        sum -= A[i];
    }

    return sum;
}

No Gauss formula, only simple and plain separate for loops that give an O(N) or O(N * log(N)) and 100% score:

function solution(A) {

    if(!A.length){
        return 1; //Just because if empty this is the only one missing.
    }

    let fullSum = 0;
    let sum = 0;

    for(let i = 0; i <= A.length; i++){
        fullSum += i+1;
    }

    for(let i = 0; i < A.length; i++){
        sum += A[i];
    }    

    return fullSum - sum;

}

Try utilizing Math.min , Math.max , while loop

var Arr = [];

Arr[0] = 2
Arr[1] = 3
Arr[2] = 1
Arr[3] = 4
Arr[4] = 6

var min = Math.min.apply(Math, Arr),
  max = Math.max.apply(Math, Arr),
  n = max - 1;

while (n > min) {

  if (Arr.indexOf(n) === -1) {
    console.log(n);
    break;
  } 

  --n;

}

This should be work good:

function solution(A) {

      // Size of the A array
      const size = A.length;

      // sum of the current values
      const arrSum = A.reduce((a, b) => a + b, 0);

      // sum of all values including the missing number
      const sum = (size + 1) * (size + 2) / 2;

      // return substruction of all - current
      return (sum - arrSum);

    }

This got me 100%

function solution(A) {
if (A.length === 0 || !A) {
    return 1;
}

A.sort((a, b) => a - b);
let count = A[0];
if (count !== 1) { return 1 }
for (let i = 0; i <= A.length; i++) {
    if (A[i + 1] === count + 1) {
        count ++;
        continue
    }
    return count + 1;
}

}

// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');

function solution(A) {
  if (!A.length) return 1;
  A = A.sort((a, b) => a - b);
  for (let i = 0; i < A.length + 1; i++) {
    if (A[i] !== i + 1) {
      return i + 1;
    }
  }
}

My 100% JavaScript solution:

function solution(A) {

    const N = A.length;

    // use the Gauss formula
    const sumNatural = (N + 1) * (N + 2) / 2;

    // actual sum with the missing number (smaller than sumNatural above)
    const actualSum = A.reduce((sum, num) => sum += num, 0);
    
    // the difference between sums is the missing number
    return sumNatural - actualSum;

}

I wonder why there isn't any answer using a hashtable. It's obvious that we need to iterate this array from start to end. Therefore, best solution we can have is O(n). I simply map numbers, and access them with O(1) in another iteration.

If all numbers are tagged as true, it means it's either an empty array, or it doesn't contain missing number. Either way length + 1 returns the expected output.

It returns 1 for [], and it returns 3 for [1,2].

// you can write to stdout for debugging purposes, e.g.

function solution(A) {
    // write your code in JavaScript (Node.js 8.9.4)
    let nums = new Map()
    for (let i = 0; i < A.length; i++) {
        nums[A[i]] = true;
    }

    for (let i = 1; i < A.length + 1; i++) {
        if (nums[i]) { continue; }
        else { return i;}
    }

    return A.length + 1;
}
function solution(A) {
    // write your code in JavaScript (Node.js 8.9.4)
    const n = A.length+1
    return (n*(n+1)/2) - A.reduce((a, b) => a + b, 0)
}

Explanation:

The formula for sum of natural numbers => n(n+1)/2
where n is the last number or last nth term. In our case, n will be our array.length. But the question states that exactly one item is missing, meaning the last nth term is array.length +1.

To find the expected sum of all our natural numbers,
We can deduct the total of the available numbers (A.reduce((a, b) => a + b, 0)) from the expected sum n(n+1)/2 to arrive at the missing number.

I had the same problem with my code:

function solution(A) {
    var i, next;

    A.sort();

    next = 1;
    for (i=0; i<A.length; i++){
        if (A[i] != next) return next;
        next++;
    }

    return next;
}

Altough it scored 100% in correctness, it returned wrong answer in all the performance tests.

The same code in C receives 100% on both:

int cmpfunc (const void * a, const void * b){
   return ( *(int*)a - *(int*)b );
}

int solution(int a[], int n) {
    int i, next;

    qsort(a, n, sizeof(int), cmpfunc);

    next = 1;
    for (i=0; i<n; i++){
        if (a[i] != next) return next;
        next++;
    }

    return next;
}

I got an alternative 100% correctness/performance solution without the Gauss formula, sorting the array first instead:

function solution(A) {
    A.sort((a, b) => a-b);
    
    for(let i=0; i<A.length; i++){
       if(A[i] != i+1) {
           return 0;
       }
    }
    return 1;
}
发布评论

评论列表(0)

  1. 暂无评论