【问题标题】:Find the longest sub array of consecutive numbers with a while loop使用while循环查找最长的连续数字子数组
【发布时间】:2025-11-26 21:45:01
【问题描述】:

我想编写一个带有 while 语句的函数,用于确定正整数数组中最大连续子数组的长度。 (至少有一个连续的数组。)例如:

Input: [6, 7, 8, 6, 12, 1, 2, 3, 4] --> [1,2,3,4]
Output: 4

Input: [5, 6, 1, 8, 9, 7]  --> [1,8,9]
Output: 3

通常我稍后会尝试使用 for 循环和 array.push 方法,但是,为了获得更多练习,我想使用 while 循环和另一种“数组延长”方法,不知道它是如何调用的,见下文。

我的尝试:

function longestSub (input) {

  let i=0;
  let idx=0;
  let counterArr=[1];                   //init. to 1 because input [4,5,3] equals sub-length 2

  while(i<input.length) {

    if (input[i]+1 > input[i]) {
      counterArr[0+idx] += 1  
    }
    else {
      i=input.indexOf(input[i]);                     //should start loop at this i-value again
      idx +=1;
      counterArr[0+idx] = 1;                         //should init new array index
    }
    i++
  }
return Math.max(...counterArr)
  }

我的想法是,else 语句会在 if 语句失败时重置 if 语句,并使用更新的变量从失败的位置重新开始。它还将使用值 1 初始化另一个数组索引,随后使用 if 语句进行更新。

最后我有一个类似 [1,2,3] 的 counterArr,其中 3 代表最大的连续子数组。感谢大家阅读本文或帮助像我这样的初学者更深入地了解 Javascript。

【问题讨论】:

  • 你想只获取连续子数组的长度还是值?

标签: javascript


【解决方案1】:

这是一个使用while循环的简单解决方案:

let arr =[6, 7, 8, 6, 12, 1, 2, 3, 4]
let endIndx = 0, maxLength = 0, indx = 1,tempMax = 0;
while (indx < arr.length) {
  if (arr[indx] > arr[indx - 1])
    tempMax++;
  else {
    if (maxLength <= tempMax) {
      maxLength = tempMax+1
      endIndx = indx
      tempMax=0;
    }
  }
  ++indx
}
if (maxLength < tempMax) {
      maxLength = tempMax
      endIndx = indx
    }
console.log("Sub array of consecutive numbers: ", arr.slice(endIndx-maxLength,endIndx))
console.log("Output :",maxLength)

【讨论】:

    【解决方案2】:

    你可以采取一种方法,只计算长度,如果是连续项目,则检查最大找到的长度。

    function longestSub(input) {
        let i = 1,          // omit first element and use later element before this index
            max = 0,
            tempLength = 1; // initialize with one
        
        if (!input.length) return 0;
    
        while (i < input.length) {
            if (input[i - 1] < input[i]) {
                tempLength++;
            } else {
                if (max < tempLength) max = tempLength;
                tempLength = 1;
            }
            i++;
        }
        if (max < tempLength) max = tempLength;
        return max;
    }
    
    console.log(longestSub([]));                              // 0
    console.log(longestSub([6, 7, 8, 6, 12]));                // 3
    console.log(longestSub([5, 6, 1, 2, 8, 9, 7]));           // 4
    console.log(longestSub([6, 7, 8, 6, 12, 1, 2, 3, 4, 5])); // 5

    【讨论】:

    • @Nina,感谢您的回复。我刚刚使用输入 ([6, 7, 8, 6, 12, 1 ,2 ,3, 4, 5]) 尝试了您的解决方案,它应该返回 5 因为 (1,2,3,4,5) 但它返回 3。也许我应该提供一个更好的示例输入,对此感到抱歉。
    【解决方案3】:

    除非这真的是一个学习练习,否则我宁愿专注于方法而不是实现。

    创建一个将数字数组分割成连续数字数组的函数:

    前两个条件处理最简单的情况:

    • 如果输入为空,则输出为空[] -> []
    • 如果输入恰好是一个元素,则输出已知[42] -> [[42]]

    然后是它的“肉”。输出是一个数组数组。让我们首先使用初始数组的第一个元素创建第一个子数组。让我们使用[6, 7, 8, 6, 12, 1 ,2 ,3, 4, 5] 作为输入。

    [[6]] 开始,然后遍历[7, 8, 6, 12, 1 ,2 ,3, 4, 5]。以下是每次迭代的结果:

    1. 7 &gt; 6 真 -> [[6,7]]
    2. 8 &gt; 7 真 -> [[6,7,8]]
    3. 6 &gt; 8 假 -> [[6],[6,7,8]]
    4. 12 &gt; 6 真 -> [[6,12],[6,7,8]]
    5. 1 &gt; 12 假 -> [[1],[6,12],[6,7,8]]
    6. 2 &gt; 1 真 -> [[1,2],[6,12],[6,7,8]]
    7. 3 &gt; 2 真 -> [[1,2,3],[6,12],[6,7,8]]
    8. 4 &gt; 3 真 -> [[1,2,3,4],[6,12],[6,7,8]]
    9. 5 &gt; 4 真 -> [[1,2,3,4,5],[6,12],[6,7,8]]
    const slices =
      xs =>
          xs.length === 0 ? []
        : xs.length === 1 ? [[xs[0]]]
                          : xs.slice(1).reduce
                              ( ([h, ...t], x) =>
                                  x >= h[h.length - 1]
                                    ? [h.concat(x), ...t]
                                    : [[x], h, ...t]
                              , [[xs[0]]]
                              );
    
    slices([6, 7, 8, 6, 12, 1 ,2 ,3, 4, 5]);
    
    //=> [ [1, 2, 3, 4, 5]
    //=> , [6, 12]
    //=> , [6, 7, 8]
    //=> ]
    

    然后你创建一个函数,它接受一个切片数组并返回最大的一个:

    const max_slices =
      xs =>
        xs.reduce
          ( (a, b) =>
              a.length > b.length
                ? a
                : b
          );
    
    max_slices(slices([6, 7, 8, 6, 12, 1 ,2 ,3, 4, 5]));
    
    //=> [1, 2, 3, 4, 5]
    

    【讨论】:

    • @customcommander,感谢您的帮助。我想知道你是否可以在你的第一个函数中添加一个或两个 cmets,因为它很漂亮,但也有点难以理解(对我来说)。