开发者

Arrays - Find missing numbers in a Sequence

I'm trying to find an easy way to loop (iterate) over an array to find all the开发者_StackOverflow missing numbers in a sequence, the array will look a bit like the one below.

var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];

For the array above I would need 0189462 and 0189464 logged out.

UPDATE : this is the exact solution I used from Soufiane's answer.

var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
var mia= [];

    for(var i = 1; i < numArray.length; i++) 
    {     
        if(numArray[i] - numArray[i-1] != 1) 
        {         
            var x = numArray[i] - numArray[i-1];
            var j = 1;
            while (j<x)
            {
                mia.push(numArray[i-1]+j);
                j++;
            }
        }
    }
alert(mia) // returns [0189462, 0189464]

UPDATE

Here's a neater version using .reduce

var numArray = [0189459, 0189460, 0189461, 0189463, 0189466];
var mia = numArray.reduce(function(acc, cur, ind, arr) {
  var diff = cur - arr[ind-1];
  if (diff > 1) {
    var i = 1;
    while (i < diff) {
      acc.push(arr[ind-1]+i);
      i++;
    }
  }
  return acc;
}, []);
console.log(mia);


If you know that the numbers are sorted and increasing:

for(var i = 1; i < numArray.length; i++) {
    if(numArray[i] - numArray[i-1] != 1) {
           //Not consecutive sequence, here you can break or do whatever you want
    }
}


ES6-Style

var arr = [0189459, 0189460, 0189461, 0189463, 0189465]; 
var [min,max] = [Math.min(...arr), Math.max(...arr)];
var out = Array.from(Array(max-min),(v,i)=>i+min).filter(i=>!arr.includes(i));

Result: [189462, 189464]


Watch your leading zeroes, they will be dropped when the array is interpreted-

var A= [0189459, 0189460, 0189461, 0189463, 0189465]

(A returns [189459,189460,189461,189463,189465])

function absent(arr){
    var mia= [], min= Math.min.apply('',arr), max= Math.max.apply('',arr);
    while(min<max){
        if(arr.indexOf(++min)== -1) mia.push(min);
    }
    return mia;
}

var A= [0189459, 0189460, 0189461, 0189463, 0189465]; alert(absent(A))

/* returned value: (Array) 189462,189464 */


To find a missing number in a sequence, First of all, We need to sort an array. Then we can identify what number is missing. I am providing here full code with some test scenarios. this code will identify only missing positive number, if you pass negative values even then it gives positive number.

function findMissingNumber(inputAr) {
  // Sort array
  sortArray(inputAr);

  // finding missing number here
  var result = 0;
  if (inputAr[0] > 1 || inputAr[inputAr.length - 1] < 1) {
    result = 1;
  } else {
    for (var i = 0; i < inputAr.length; i++) {
      if ((inputAr[i + 1] - inputAr[i]) > 1) {
        result = inputAr[i] + 1;
      }
    }
  }
  if (!result) {
    result = inputAr[inputAr.length - 1] + 1;
  }
  return result;
}

function sortArray(inputAr) {
  var temp;
  for (var i = 0; i < inputAr.length; i++) {
    for (var j = i + 1; j < inputAr.length; j++) {
      if (inputAr[j] < inputAr[i]) {
        temp = inputAr[j];
        inputAr[j] = inputAr[i];
        inputAr[i] = temp;
      }
    }
  }
}

console.log(findMissingNumber([1, 3, 6, 4, 1, 2]));
console.log(findMissingNumber([1, 2, 3]));
console.log(findMissingNumber([85]));
console.log(findMissingNumber([86, 85]));
console.log(findMissingNumber([0, 1000]));


This can now be done easily as a one-liner with the find method:

const arr = [1,2,3,5,6,7,8,9];

return arr.find((x,i) => arr[i+1]-x > 1) + 1

//4


const findMissing = (arr) => {
const min = Math.min(...arr);
const max = Math.max(...arr);
// add missing numbers in the array
let newArr = Array.from(Array(max-min), (v, i) => {
    return i + min
});
// compare the full array with the old missing array
let filter = newArr.filter(i => {
    return !arr.includes(i)
})
return filter;
};


const findMissing = (numarr) => {
  for(let i = 1; i <= numarr.length; i++) {
      if(i - numarr[i-1] !== 0) {
        console.log('found it', i)
        break;
      } else if(i === numarr.length) console.log('found it', numarr.length + 1)
    }
  };

console.log(findMissing([1,2,3,4,5,6,7,8,9,10,11,12,13,14]))


It would be fairly straightforward to sort the array:

numArray.sort();

Then, depending upon what was easiest for you:

  1. You could just traverse the array, catching sequential patterns and checking them as you go.
  2. You could split the array into multiple arrays of sequential numbers and then check each of those separate arrays.
  3. You could reduce the sorted array to an array of pairs where each pair is a start and end sequence and then compare those sequence start/ends to your other data.


function missingNum(nums){
    const numberArray = nums.sort((num1, num2)=>{
      return num1 - num2;
   });
   for (let i=0; i < numberArray.length; i++){
      if(i !== numberArray[i]){
        return i;
      }
   }
 }
 console.log(missingNum([0,3,5,8,4,6,1,9,7]))


Please check below code.....

function solution(A) {
   var max = Math.max.apply(Math, A);
   if(A.indexOf(1)<0) return 1;
   var t = (max*(max+1)/2) - A.reduce(function(a,b){return a+b});
   return t>0?t:max+1;
}


Try as shown below

// Find the missing number
let numArray = [0189459, 0189460, 0189461, 0189463, 0189468];
let numLen = numArray.length;
let actLen = Number(numArray[numLen-1])-Number(numArray[0]);
let  allNumber = [];

for(let i=0; i<=actLen; i++){
  allNumber.push(Number(numArray[0])+i);
}
[...allNumber].forEach(ele=>{
  if(!numArray.includes(ele)){
    console.log('Missing Number -> '+ele);
  }
})


I use a recursive function for this.

function findMissing(arr, start, stop) {

    var current = start,
        next = stop,
        collector = new Array();

    function parseMissing(a, key) {
        if(key+1 == a.length) return;

        current = a[key];
        next = a[key + 1];

        if(next - current !== 1) {
            collector.push(current + 1);
            // insert current+1 at key+1
            a = a.slice( 0, key+1 ).concat( current+1 ).concat( a.slice( key +1 ) );
            return parseMissing(a, key+1);
        }

        return parseMissing(a, key+1);
    }

    parseMissing(arr, 0);
    return collector;
}

Not the best idea if you are looking through a huge set of numbers. FAIR WARNING: recursive functions are resource intensive (pointers and stuff) and this might give you unexpected results if you are working with huge numbers. You can see the jsfiddle. This also assumes you have the array sorted.

Basically, you pass the "findMissing()" function the array you want to use, the starting number and stopping number and let it go from there.

So:

var missingArr = findMissing(sequenceArr, 1, 10);


let missing = [];
let numArray = [3,5,1,8,9,36];
const sortedNumArray = numArray.sort((a, b) => a - b);
sortedNumArray.reduce((acc, current) => {
  let next = acc + 1;
  if (next !== current) {
    for(next; next < current; next++) {
      missing.push(next);
    }
  }
  return current;
});


Assuming that there are no duplicates

let numberArray = [];

for (let i = 1; i <= 100; i++) {
  numberArray.push(i);
}
let deletedArray = numberArray.splice(30, 1);
let sortedArray = numberArray.sort((a, b) => a - b);
let array = sortedArray;

function findMissingNumber(arr, sizeOfArray) {
  total = (sizeOfArray * (sizeOfArray + 1)) / 2;
  console.log(total);
  for (i = 0; i < arr.length; i++) {
    total -= arr[i];
  }
  return total;
}

console.log(findMissingNumber(array, 100));


Here is the most efficient and simple way to find the missing numbers in the array. There is only one loop and complexity is O(n).

/**
 * 
 * @param {*} item Takes only the sorted array
 */
function getAllMissingNumbers(item) {
  let first = 0;
  let second = 1;
  let currentValue = item[0];
  const container = [];
  while (first < second && item[second]) {
    if ((item[first] + 1) !== item[second]) { // Not in sequence so adds the missing numbers in an array
      if ((currentValue + 1) === item[second]) { // Moves the first & second pointer
        first = second;
        second++;
        currentValue = item[first];
      } else { // Adds the missing number between two number
        container.push(++currentValue);
      }
    } else { // Numbers are in sequence so just moves the first & second pointer
      first = second;
      second++;
      currentValue = item[first];
    }
  }
  return container;
}

console.log(getAllMissingNumbers([0189459, 0189460, 0189461, 0189463, 0189465].sort( (a, b) => a - b )));
console.log(getAllMissingNumbers([-5,2,3,9]));


Adding one more similar method

  1. Find the min and max of the numbers in the array
  2. Loop with the max and min numbers to get the full list
  3. compare the full list of numbers with the input array to get the difference

const array = [0189459, 0189460, 0189461, 0189463, 0189465]

const max = Math.max(...array)

const min = Math.min(...array)

let wholeNumber = []

for(var i = min ;i<=max ;i++ ){
  wholeNumber.push(i)
}

const missing = wholeNumber.filter((v)=>!array.includes(v))

console.log('wholeNumber',wholeNumber)

console.log('missingNumber',missing)


Here's a variant of @Mark Walters's function which adds the ability to specify a lower boundary for your sequence, for example if you know that your sequence should always begin at 0189455, or some other number like 1.

It should also be possible to adjust this code to check for an upper boundary, but at the moment it can only look for lower boundaries.

//Our first example array.
var numArray = [0189459, 0189460, 0189461, 0189463, 0189465];
//For this array the lowerBoundary will be 0189455
var numArrayLowerBoundary = 0189455;

//Our second example array.
var simpleArray = [3, 5, 6, 7, 8, 10, 11, 13];
//For this Array the lower boundary will be 1
var simpleArrayLowerBoundary = 1;

//Build a html string so we can show our results nicely in a div
var html = "numArray = [0189459, 0189460, 0189461, 0189463, 0189465]<br>"
html += "Its  lowerBoundary is \"0189455\"<br>"
html += "The following numbers are missing from the numArray:<br>"
html += findMissingNumbers(numArray, numArrayLowerBoundary);
html += "<br><br>"
html += "simpleArray = [3, 5, 6, 7, 8, 10, 11, 13]<br>"
html += "Its  lowerBoundary is \"1\".<br>"
html += "The following numbers are missing from the simpleArray:<br>"
html += findMissingNumbers(simpleArray, simpleArrayLowerBoundary);

//Display the results in a div
document.getElementById("log").innerHTML=html;

//This is the function used to find missing numbers!
//Copy/paste this if you just want the function and don't need the demo code.
function findMissingNumbers(arrSequence, lowerBoundary) {
  var mia = [];
  for (var i = 0; i < arrSequence.length; i++) {
    if (i === 0) {
      //If the first thing in the array isn't exactly
      //equal to the lowerBoundary...
      if (arrSequence[i] !== lowerBoundary) {
        //Count up from lowerBoundary, incrementing 1
        //each time, until we reach the
        //value one less than the first thing in the array.
        var x = arrSequence[i];
        var j = lowerBoundary;
        while (j < x) {
          mia.push(j); //Add each "missing" number to the array
          j++;
        }
      } //end if
    } else {
      //If the difference between two array indexes is not
      //exactly 1 there are one or more numbers missing from this sequence.
      if (arrSequence[i] - arrSequence[i - 1] !== 1) {
        //List the missing numbers by adding 1 to the value
        //of the previous array index x times.
        //x is the size of the "gap" i.e. the number of missing numbers
        //in this sequence.      
        var x = arrSequence[i] - arrSequence[i - 1];
        var j = 1;
        while (j < x) {
          mia.push(arrSequence[i - 1] + j); //Add each "missing" num to the array
          j++;
        }
      } //end if
    } //end else
  } //end for
  //Returns any missing numbers, assuming that lowerBoundary is the
  //intended first number in the sequence.
  return mia;
}
<div id="log"></div> <!-- Just used to display the demo code -->

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜