假设数组已排序,您如何在前N个自然数的数组中找到1个,2个和3个缺失数?
同样,假设数组已排序,以下代码将用于返回一个缺失的值(由于return
语句)
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来工作 - 如果arr [i]!= i + 1,我试图通过将缺失值推送到一个新数组来编写它,但同样,这只会返回第一个缺失值的正确值。
你会如何解决这个问题?
答案 0 :(得分:4)
在数组中查找最小值和最大值,使用Array.from()
过滤该数组,使用提供的数组过滤来创建数组,以返回缺少的数字。
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]));
&#13;
答案 1 :(得分:3)
另一个应该有效的实现。在时间复杂度方面,它应该是O(n)
。
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));
&#13;
答案 2 :(得分:1)
您需要在此处进行两项更改。
以下是更新的代码段:
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));
答案 3 :(得分:1)
您可以使用Array.prototype.reduce()
,do..while
循环
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);
答案 4 :(得分:0)
您可以使用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])]);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 5 :(得分:0)
这是(其他)非ES6解决方案。内部循环可能会被重新加工,不需要排序作为倒数第二行。
无论内部循环如何,最坏的情况都应该在O(n)x 2中以1和数组的最大值对齐的数组运行 - 内部循环只运行多次以找到超过一个“差距”。
也许循环不如this non-ES6 implementation优雅,但另一方面,我的优势是不会引入除返回的数组之外的任何变量。
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