Reputation: 427
Assuming an array is sorted, how would you find 1, 2, and 3 missing numbers in an array of the first N natural numbers?
Again, assuming the array is sorted, the following code will work for returning one value that is missing (due to the return
statement)
function findMissingNumbers(array) {
for (var i = 0; i < array.length; i++) {
if (array[i] != (i + 1)) {
return i + 1;
}
}
return 'no missing numbers found';
}
var missingArr = [1, 3, 4, 5, 6, 7];
console.log(findMissingNumbers(missingArr));
I have seen many responses that do the same (find one missing value) by taking the sum and the expected sum and finding the missing value by subtracting the sum from the expected sum however, this too will only find one missing value.
I know that this code will not work by using i as I am-- I tried to write it by pushing the missing values into a new array if arr[i] != i + 1, but again, this will only return the correct value for the first missing value.
How would you approach this problem?
Upvotes: 3
Views: 2127
Reputation: 12561
Here is an(other) non-ES6 solution. The inner loop could probably be reworked to not require sorting as the next to last line.
Regardless of the inner loop it should at worst run in O(n) x 2 vis a vis an array bounded by 1 and the max value of the array -- the inner loop is only run more than once to find more than one "gaps".
Maybe the loop is less elegant than this non-ES6 implementation, but on the other hand mine has the advantage of not introducing any variables other than the array that gets returned.
function findMissingNumbers(array) {
var missingNumbers = [];
for (var i=0, n=array.length; i<n; i++) {
if (array[i] > (i + 1 + missingNumbers.length)) {
for (j=1, k = array[i] - (i + 1 + missingNumbers.length); j<=k; j++) {
missingNumbers.push(array[i] - j);
}
}
}
missingNumbers.sort();
return missingNumbers;
}
var missingArr = [1, 4, 5, 6, 7, 9];
console.log(findMissingNumbers(missingArr).join(",")); //2,3,8
Upvotes: 0
Reputation: 386654
You could use Set
function* findMissingNumbers(array) {
var numbers = new Set(array),
i = 1;
while (numbers.size) {
if (numbers.has(i)) {
numbers.delete(i);
} else {
yield i;
}
i++;
}
}
console.log([...findMissingNumbers([1, 3, 4, 5, 6, 7])]);
console.log([...findMissingNumbers([6, 7])]);
console.log([...findMissingNumbers([1, 2, 3, 4, 5, 6, 7])]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 1
You can use Array.prototype.reduce()
, do..while
loop
var missingArr = [1, 3, 4, 5, 6, 7, 9];
var res = [];
missingArr.reduce(function(a, b) {
var i = a + 1;
if (i !== b) {
do {
res.push(i++)
} while (i < b);
}
return b
});
console.log(res);
Upvotes: 1
Reputation: 4944
You'll need to make two changes here.
Below is the updated code snippet:
function findMissingNumbers(array) {
var resultsArray = [];
var missedNumbers = 0;
for (var i = 0; i < array.length; i++) {
var expectedValue = i + 1 + missedNumbers;
if (array[i] != expectedValue) {
var segmentCountOfMissedNumbers = array[i] - expectedValue;
for (var ii = 0; ii < segmentCountOfMissedNumbers; ii++) {
resultsArray.push(expectedValue + ii);
}
missedNumbers = missedNumbers + segmentCountOfMissedNumbers;
}
}
if (resultsArray.length > 0) {
return resultsArray;
} else {
return 'no missing numbers found';
}
}
var missingArr = [3, 5, 9];
console.log(findMissingNumbers(missingArr));
Upvotes: 1
Reputation: 9878
One more implementation that should work. It should be O(n)
in terms of time complexity.
function findMissingNumbers(array) {
var missingNumbers = [];
var endInteger = array[array.length - 1];
var missingNumberCounter = 0;
for (var i=0; i < endInteger; i++) {
if (array[i - missingNumberCounter] != (i + 1)) {
missingNumbers.push(i + 1);
missingNumberCounter++;
}
}
return missingNumbers;
}
var missingArr = [1, 3, 4, 5, 6, 7];
var missingArr2 = [2, 3, 4, 9, 10, 11];
console.log(findMissingNumbers(missingArr));
console.log(findMissingNumbers(missingArr2));
Upvotes: 3
Reputation: 122057
Find minimum and maxium number in array, create array from them using Array.from()
filter that array with provided array to return missing numbers.
function findMissingNumbers(arr) {
var min = Math.min(...arr);
var max = Math.max(...arr);
var all = Array.from(Array(max - min + 1), (e, i) => i + min)
return all.filter(e => !arr.includes(e))
}
console.log(findMissingNumbers([1, 3, 4, 5, 6, 7]));
console.log(findMissingNumbers([10, 16, 8]));
Upvotes: 4