[英]Javascript: Keep getting one off when looking for consecutive numbers in array
我正在做一些編碼練習,並且在網上發現了一些問題。
當返回數組中的連續數字時,我總是比預期低1個整數。
function LongestConsecutive(arr) {
arr.sort((a,b) => {return a-b});
let highest = 0;
let counter = 0;
let prevNum;
arr.forEach((num,index,arr) => {
if (prevNum === undefined) {
prevNum = num
} else {
if (num + 1 == arr[index + 1]) {
counter += 1;
highest = Math.max(highest,counter)
} else {
counter = 0;
}
}
})
return highest;
}
例如,輸入[5、6、1、2、8、9、7]應返回5-因為排序時有5個連續數字。 我一直比我要得到的低一個,因此我得到4。唯一正確的答案是當我返回“最高+ 1”時,這顯然是在避免問題。
第一次迭代將擊中
if (prevNum === undefined) {
prevNum = num;
}
但是那已經不是第一個連續數字了嗎? 所以counter = 1;
highest = 1;
應該在這里。
接下來,您重置counter = 0;
在else
情況下。 為什么? 至少有一個連續的數字,因此請將其重置為1
。
然后,您實際上並沒有使用prevNum
。 if (prevNum === undefined)
可以用if (index === 1)
代替。
然后,您檢查當前數字( num
)是否在下一個數字( arr[index + 1]
)之前,但是您跳過了對第一個索引的檢查。 如何檢查當前數字是否接替前一個數字?
此代碼使用上述更改以及一些代碼質量更改:
function longestConsecutive(arr) { // Non-constructor functions start with a lower-case letter
arr.sort((a, b) => a - b); // Use expression form
let highest = 0;
let counter = 0;
arr.forEach((num, index, arr) => {
if (index === 0) {
highest = 1;
counter = 1;
} else if (num - 1 === arr[index - 1]) { // Merge `else if`, use strict equal
counter += 1;
highest = Math.max(highest, counter);
} else {
counter = 1;
}
});
return highest;
}
好吧,根據連續的定義,您將始終擁有一個連續的數字。 因此,您需要從1開始計數。
也可以用array:reduce實現
function longestRun(array) { const { streak } = array .sort((a, b) => a - b) // sort into ascending order .reduce(({ count, streak }, current, index, arr) => { if (current === arr[index - 1] + 1) { count++; // increment if 1 more than previous } else { count = 1; // else reset to 1 } return {count, streak: Math.max(streak, count)}; }, { count: 0, streak: 0 }); // initial value is 0,0 in case of empty array return streak; } console.log(longestRun([])); // 0 console.log(longestRun([0])); // 1 console.log(longestRun([0, 1])); // 2 console.log(longestRun([0, 1, 0])); // 2 console.log(longestRun([0, 0, 0])); // 1 console.log(longestRun([2, 0, 1, 0, 3, 0])); // 4
如果能夠通過條件將數組拆分為子數組,則可以通過在非連續點處拆分數組來實現。
const arr = [5, 6, 1, 2, 8, 9, 7, 11, 12, 13, 14] // utility for splitting array at condition points const splitBy = (arr, cond) => arr.reduce((a, cur, i, src) => { if(cond(cur, i, src)){ a.push([]) } a[a.length - 1].push(cur) return a }, []) const consecutives = splitBy( arr.sort((a, b) => a - b), (cur, i, src) => cur !== src[i-1] + 1 ).sort((a, b) => b.length - a.length) // largest consecutive list will be the first array console.log(consecutives[0].length)
我嘗試了這段代碼(與問題中發布的代碼不同),它給出了預期的結果。 此外,如果有兩組連續的相同(且最大)長度的數字被打印,
var arr = [5, 6, 1, 2, 8, 9, 7, 99, 98];
arr.sort((a, b) => a - b);
var prevNum = arr[0];
var consecutiveNumbersArr = [prevNum];
// Map of consecutiveNumbersArr array as key and
// the array length as values
var arrMap = new Map();
for (let i = 1; i < arr.length; i++) {
let num = arr[i];
if (num === prevNum+1) {
prevNum = num;
consecutiveNumbersArr.push(num);
continue;
}
arrMap.set(consecutiveNumbersArr, consecutiveNumbersArr.length);
consecutiveNumbersArr = [];
consecutiveNumbersArr.push(num);
prevNum = num;
}
arrMap.set(consecutiveNumbersArr, consecutiveNumbersArr.length);
// the largest length of all the consecutive numbers array
var largest = 0;
for (let value of arrMap.values()) {
if (value > largest) {
largest = value;
}
}
// print the result - the largest consecutive array
for (let [key, value] of arrMap) {
if (value === largest) {
console.log("RESULT: " + key);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.