【问题标题】:Arrays - Find missing numbers in a Sequence数组 - 在序列中查找缺失的数字
【发布时间】:2024-01-04 11:17:01
【问题描述】:

我正在尝试找到一种简单的方法来循环(迭代)数组以查找序列中所有丢失的数字,该数组看起来有点像下面的那个。

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

对于上面的数组,我需要退出 01894620189464

更新:这是我从 Soufiane 的回答中使用的确切解决方案。

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]

更新

这是一个使用 .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);

【问题讨论】:

  • 您可以遍历数组并比较每两个元素。
  • 您的解决方案有两个 O(n2) 循环。我有一个简单的解决方案 O(n) *.com/a/68314385/4646531

标签: javascript arrays loops sequence


【解决方案1】:

添加一个类似的方法

  1. 找出数组中数字的最小值和最大值
  2. 循环使用最大和最小数字以获取完整列表
  3. 将完整的数字列表与输入数组进行比较以获得差异

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)

【讨论】:

    【解决方案2】:

    这是查找数组中缺失数字的最有效和最简单的方法。只有一个循环,复杂度为 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]));

    【讨论】:

      【解决方案3】:

      现在可以使用 find 方法作为单行轻松完成:

      const arr = [1,2,3,5,6,7,8,9];
      
      return arr.find((x,i) => arr[i+1]-x > 1) + 1
      
      //4
      

      【讨论】:

        【解决方案4】:

        如下图试试

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

        【讨论】:

          【解决方案5】:

          假设没有重复

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

          【讨论】:

            【解决方案6】:
            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]))
            

            【讨论】:

              【解决方案7】:
              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;
              };
              

              【讨论】:

                【解决方案8】:

                ES6 风格

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

                结果:[189462, 189464]

                【讨论】:

                • 答案有效,所以我的 +1。最好能解释一下它是如何工作的;-)
                【解决方案9】:

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

                【讨论】:

                • 这不考虑顺序缺失值以及其他一些问题。试试这个例子: const numArray = [3,5,1,8,9]
                【解决方案10】:

                请检查以下代码.....

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

                【讨论】:

                  【解决方案11】:
                  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]))
                  

                  【讨论】:

                    【解决方案12】:

                    要在一个序列中找到一个缺失的数字,首先,我们需要对一个数组进行排序。然后我们可以确定缺少哪个数字。我在这里提供了带有一些测试场景的完整代码。此代码将仅识别缺少的正数,如果您传递负值,即使它给出正数。

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

                    【讨论】:

                    【解决方案13】:

                    这是@Mark Walters 的function 的变体,它增加了为序列指定下边界的功能,例如,如果您知道序列应该始终以0189455 或其他一些数字(如1)开始.

                    也应该可以调整此代码以检查上边界,但目前它只能寻找下边界。

                    //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;
                    }
                    &lt;div id="log"&gt;&lt;/div&gt; &lt;!-- Just used to display the demo code --&gt;

                    【讨论】:

                      【解决方案14】:

                      我为此使用递归函数。

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

                      如果您正在查看大量数字,这不是最好的主意。公平警告:递归函数是资源密集型的(指针和东西),如果您处理大量数字,这可能会给您带来意想不到的结果。你可以看到jsfiddle。这也假设您已对数组进行了排序。

                      基本上,您将要使用的数组、起始编号和终止编号传递给“findMissing()”函数,然后让它从那里开始。

                      所以:

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

                      【讨论】:

                        【解决方案15】:

                        注意你的前导零,当数组被解释时它们将被删除-

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

                        (A 返回 [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]; 警报(缺席(A))

                        /* 返回值:(数组) 189462,189464 */

                        【讨论】:

                          【解决方案16】:

                          对数组进行排序会相当简单:

                          numArray.sort();
                          

                          然后,取决于对您来说最简单的方法:

                          1. 您可以只遍历数组,捕捉顺序模式并随时检查它们。
                          2. 您可以将数组拆分为多个序列号数组,然后检查每个单独的数组。
                          3. 您可以将排序后的数组简化为一个对数组,其中每对都是开始和结束序列,然后将这些序列开始/结束与您的其他数据进行比较。

                          【讨论】:

                            【解决方案17】:

                            如果你知道数字是有序且递增的:

                            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
                                }
                            }
                            

                            【讨论】:

                            • 谢谢 Soufiane,因为该数组将包含大约 100 个数字,因此我将如何记录不存在的实际数字,我可能又会很厚。
                            • @Mark:numArray[i]numArray[i-1] 之间的每个数字,如果差值大于1,则不在数组中。
                            • 是的,您将遍历数组中的每个项目,并捕捉丢失的数字,当差值为 X (X != 1) 时,您的丢失数字是:numArray[i- 1] + j (j>0 和 j
                            最近更新 更多