在数组中找到相同数字的最长连续出现次数

7
使用JavaScript,我正在尝试找到一种方法来查找数组中相同数字(在本例中为1)的最长出现次数。
例如,这是一个示例数组: [2,5,3,1,1,1,3,7,9,6,4,1,1,1,1,1,4,7,2,3,1,1,4,3] 我想编写一个函数,它将返回“5”,因为数字1连续出现了5次。 (它也连续出现了3次和2次,但我想要最长的出现次数)。
到目前为止,我已经编写了:
function streak(arr) {
    var i,
        temp,
        streak,
        length = arr.length;

    for(i=0; i<length; i++) {
        if (arr[i] === 1) {
            streak += 1;
        } else {
            temp = streak;
            break;
        }
    }
}

我知道如果我找到了一个事件,就需要有一种方法来知道我上次处理到哪里,但我感觉有些困惑。

有什么指导意见吗?


3
这有帮助吗?https://dev59.com/_G035IYBdhLWcg3wBLTb - stripthesoul
12个回答

0

很不幸,一个问题被标记为重复,但它并不与这个问题相同。所以我必须在这里放置我的答案,抱歉...

let tab = [0,0,0,1,1,1,0,0,0,0,1,0,1,1,1,1,1]
  , arr = []
  , n = 0
  , res = null ;

for(let i of tab)
{
    if ( i ) { ++ n }
    else if ( n ) { arr.push(n) ; n = 0 }
}
arr.push(n) ;

res = Math.max(...arr);

console.log("Streak with 1 is ", Math.max(...arr));

这是一个比使用reduce更好的解决方案,但速度较慢,如下所示:

let tab = [0,0,0,1,1,1,0,0,0,0,1,0,1,1,1,1,1];
let arr = [];
let n = 0;
let res = null;

let loop = 0;
let start = new Date().getTime();

while (loop < 1000000){
  ++ loop;
  
  arr = [];
  for(let i of tab)
  {
      if ( i ) { ++ n }
      else if ( n ) { arr.push(n) ; n = 0 }
  }
  arr.push(n);
  res = Math.max(...arr);
}
let end = new Date().getTime();
console.log("laps old fashion = ", end - start);

loop = 0;
let streaks = null;
start = new Date().getTime();
while (loop < 1000000){
  ++ loop;
  streaks = tab.reduce((res, n) => 
    (n ? res[res.length-1]++ : res.push(0), res)
  , [0]);
  res = Math.max(...streaks);
}
end = new Date().getTime();
console.log("laps reduce = ", end - start);

console.log("Streak with 1 is ", Math.max(...arr));


0

输入数组:

const seq = [
0, 0, 0,
1, 1, 1,
1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
];

最短解决方案:

console.log(Math.max(...Array.from(seq.join("").matchAll(/(.)\1+/g), m=>m[0].length)))

使用正则表达式的替代方案(剧透:它比使用reduce()的解决方案慢约25%。请参见下面的“使用reduce()的现代方法”):

const longestSeq = (seq) => {
    let max = 0;
    seq.join("").replace(/(.)\1+/g, m=> max = Math.max(max, m.length));
    return max;
};

直接、老派的风格,易读性强且速度最快的解决方案:

let longestSeq = () => {
    let maxCount = 0,
        curCount = 0,
        curItem, prevItem,
        l = seq.length+2, // +1+1 to finish last sequence and compare 'undefined' with previous
        i = 0;
    for (; i < l; ++i) {
      curItem = seq[i];
      if (curItem === prevItem) ++curCount;
      else {
        if (curCount > maxCount) maxCount = curCount;
        curCount = 1;
        prevItem = curItem;
      }
    }
    return maxCount;
}

使用reduce()的现代方法(仅比上面的老式代码略慢):

const longestSeq = (seq) => seq
    .reduce(
        ({count, max}, item) => item === 0
        ? { count: ++count, max: Math.max(count, max) }
        : { count: 0, max: max },
      { count: 0, max: 0} )
    .max;

性能测试,Reduce() vs 旧式 for(): https://jsbench.me/ifkgsin56z/1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接