在数组中计算相同值的数量

8

我正在处理一个挑战,需要找到一个数组中最小的值并计算它出现的次数,如果这个数字出现超过一次。我认为我已经掌握了格式,但是计算结果会比实际数字多1(4而不是3)。能否有人给我一些提示?感谢任何帮助!

function small(array) {
  var smallest = array[0];
  var count = 0;
  for(var i = 0; i < array.length; i++) {
    if(array[i] < smallest) {
      smallest = array[i];
    }
    if(smallest===array[i]) {
      count++;
    }
  }
  return count;
}

small([5,6,2,2,2]);

5个回答

4

每当你获得新的最小值时,都需要进行重置。

为什么需要将计数器重置为0而不是1?

因为条件是检查 smallest === arr[i],这意味着您正在检查现在已经存储的相同元素。

function small(array){
    var smallest = array[0];
    var count = 0;
    for(var i = 0; i < array.length; i++) {
        if(array[i] < smallest) {
            smallest = array[i];
            count = 0;
        }
        if(smallest===array[i]) {
            count++;
        }
    }
    return count;
 }
 console.log(small([5,6,2,2,2]));


@Kaps 非常感谢!将其重置为0确实起作用了。这背后的逻辑是什么?因为它已经被设置为0了。 - grasshopper
@grasshopper 当你获得新的最小值时,需要进行重置。为什么是0而不是1?因为你后面有一个条件语句,它检查 smallest === arr[i],这意味着你正在检查现在存储的相同元素。 - Kaps
@YuvalBen-Arie 如果你使用重置1来运行它,你就会知道为什么不是0而是1。 - Kaps
@Kaps 我知道。没有注意到那里没有 else if(应该有的)。已经删除了评论。 - Yuval Ben-Arie

2

在这里,您可以使用两个循环,首先获取最小的数字,然后计算它出现的次数。时间复杂度仍为O(n)。

function small(array){
    var smallest = array[0];
    var count = 0;
    for(var i = 0; i < array.length; i++) {
       if(array[i] < smallest) {
           smallest = array[i];
       }
    }
    for(var i=0; i<array.length; i++){
       if(smallest===array[i]) {
           count++;
       }
    }
    return count;
}
console.log( small([5,6,2,2,2]));


1
第一次循环运行时,smallest是数组中的第一个项,因为声明时它就这样。
var smallest = array[0];

在第一次迭代中,smallest已经是5,而array[i]也是5,因为它当前是array[0],这就是循环的起点,所以它们是相同的,这意味着您在第一次迭代中的条件是成立的,并且计数增加。
你的方法不太对。最简单的方法是使用Math.min查找数组中的最小数字,然后根据它过滤数组,看看还剩下多少索引。

function small(arr) {
    let min = Math.min.apply(null, arr);
    return arr.filter(val => val === min).length;
}

console.log(small([5, 6, 2, 2, 2]));


这样做会不会在数组的每个项目中重新计算所有整数的最小值?(与首先存储最小值相反) - pinkfloydx33
不会,但是我可以通过使用Array.filter的第三个参数来确保这不是一个问题。 - adeneo
我的意思是,过滤器回调针对原始数组中的每个项执行。在该回调内部,您正在调用一个函数(Math.min)。每次调用过滤器回调时,如何不调用Math.min,从而重新计算整个数组的最小值(尽管始终是相同的结果)?或者我在这里漏掉了什么? - pinkfloydx33
@pinkfloydx33 - 正确,它确实会多次调用 Math.min,虽然对于这个例子来说并没有太大关系,但我将其移出了回调函数。 - adeneo

0

如果你替换了smallest,你应该将count设置为0。

function small(array){
    var smallest = array[0];
    var count = 0;
    for(var i = 0; i < array.length; i++) {
        if(array[i] < smallest) {
            smallest = array[i];
            count = 0;
        }
        if(smallest===array[i]) {
            count++;
        }
    }
    return count;
}
small([5,6,2,2,2]);

0

你将 smallest 设置为

array[0] 

如果语句说

smallest = array[i]

这是永远正确的。 你需要设置 smallest = 0 或 smallest = 1。


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