在前N个自然数的数组中找到1,2,3个缺失数字

时间:2017-02-06 16:17:08

标签: javascript arrays

假设数组已排序,您如何在前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,我试图通过将缺失值推送到一个新数组来编写它,但同样,这只会返回第一个缺失值的正确值。

你会如何解决这个问题?

6 个答案:

答案 0 :(得分:4)

在数组中查找最小值和最大值,使用Array.from()过滤该数组,使用提供的数组过滤来创建数组,以返回缺少的数字。

&#13;
&#13;
 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;
&#13;
&#13;

答案 1 :(得分:3)

另一个应该有效的实现。在时间复杂度方面,它应该是O(n)

&#13;
&#13;
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;
&#13;
&#13;

答案 2 :(得分:1)

您需要在此处进行两项更改。

  1. 从函数返回数组,而不是在for循环的第一次迭代中返回数字。
  2. 创建一个新变量以跟踪那些错过的数字。
  3. 以下是更新的代码段:

    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

&#13;
&#13;
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;
&#13;
&#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