簡體   English   中英

在前N個自然數的數組中找到1,2,3個缺失的數字

[英]Find 1, 2, 3 missing numbers in an array of first N natural numbers

假設數組已排序,您如何在前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,但同樣,這只會返回正確的第一個缺失值的值。

你會如何解決這個問題?

查找數組中的最小值和最大值,使用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])); 

還有一個應該有效的實現。 就時間復雜度而言應該是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)); 

您需要在此處進行兩項更改。

  1. 從函數返回一個數組,而不是在for循環的第一次迭代中返回數字。
  2. 創建一個新變量以跟蹤那些已遺漏的數字。

以下是更新的代碼段:

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));

您可以使用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); 

你可以使用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; } 

這是(其他)非ES6解決方案。 內部循環可能會被重新加工,不需要排序作為倒數第二行。

無論內部循環如何,它應該在O(n)x 2中以1和數組的最大值對齊的數組運行 - 內部循環只運行多次以找到多個“間隙” ”。

也許循環不如這個非ES6實現優雅,但另一方面,我的優勢是不會引入除返回的數組之外的任何變量。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM