可以使用Math.min从数组中获取第二个最小数字吗?

时间:2017-11-15 20:17:10

标签: javascript

我正在使用Math.min从数组中获取最小数字。但是,我也需要得到第二个最小的数字。想知道是否有办法使用Math.min执行此操作,否则寻找获得此数字的最佳方式。

以下是我所拥有的:



var arr = [15, 37, 9, 21, 55];
var min = Math.min.apply(null, arr.filter(Boolean));
var secondMin; // Get second smallest number from array here

console.log('Smallest number: ' + min);
console.log('Second smallest number: ' + secondMin);




10 个答案:

答案 0 :(得分:4)

我看到你在第一分钟使用Array.filter(但为什么?)因此,如果我们使用ES6功能,您可以先从数组中删除min,找到第二个最低值。

var secondMin = Math.min.apply(null, arr.filter(n => n != min));
为清晰起见,

编辑,除非您在计算第一个分钟时使用Array.filter(Boolean)做一些非常聪明的事情,否则您应该将数组传递给它而不进行过滤:

var min = Math.min.apply(null, arr);

答案 1 :(得分:3)

只是为了完成该线程:最快的方法是迭代所有元素,就像你可以做到的那样找到最小值。但根据您的需要,将使用两个变量:第一个最小(候选)和第二个。

该逻辑是O(N),而排序方法是O(N lg(N))。

但也许你不应该关心这只是为了练习。

如果重复应该作为独立值处理(就像.sort(...)[1]那样),那么它应该<=而不是<

&#13;
&#13;
var arr = [15, 37, 9, 21, 55];
var min = Infinity, secondMin = Infinity; 
for (var i= 0; i< arr.length; i++) {
    if (arr[i]< min) {
        secondMin = min;
        min = arr[i]; 
    } else if (arr[i]< secondMin) {
        secondMin = arr[i]; 
    }
}

console.log('Smallest number: ' + min);
console.log('Second smallest number: ' + secondMin);
&#13;
&#13;
&#13;

答案 2 :(得分:3)

@skyboyer提供了查找两个最小元素的最快算法。在O(n)时间内运行的另一种类型算法是selection(在一般的comp-sci定义中,而不是在JavaScript中通常使用的方式),它将找到k最小的元素一个数组,将元素分成较大的元素和小于k的元素。

即使大多数分区选择算法(quickselectFloyd-Rivestintroselect)在O(n)时间内运行,@ skyboyer的答案也会更快,因为您正在寻找的分区的特定性质,因为所有这些算法都有一个沉重的常数因子。

有一个实现Floyd-Rivest的javascript库,但命名为quickselect可以为你做分区:

quickselect(arr, 1)

arr将重新排列,以便arr[0]是最小值,arr[1]是第二个最小元素,其余元素按任意顺序排列。

答案 3 :(得分:2)

如果您不担心性能,可以简单地对数组进行排序。

arr.sort(function(a, b) {
  return a - b;
});

答案 4 :(得分:0)

具有降低(非常高效)的ES6溶液

const A = [8, 24, 3, 20, 1, 17]
const min = Math.min(...A)
const secondMin = A.reduce((pre, cur) => (cur < pre && cur !== min) ? cur : pre
  , Infinity)
console.log(min, secondMin)

答案 5 :(得分:0)

这将处理的@skyboyer版本正确重复:

function secondSmallest(x) {
  if (x.length < 2) return 0;

  let first = Number.MAX_VALUE;
  let second = Number.MAX_VALUE;

  for (let i = 0; i < x.length; i++) {
    let current = x[i];
    if (current < first) {
      second = first;
      first = current;
    } else if (current < second && current !== first) {
      second = current;
    }
  }
  return second;
}

console.log(secondSmallest([1, 1, 1, 1, 2]));
console.log(secondSmallest([1, 2, 1, 1, 1]));
console.log(secondSmallest([6, 3, 4, 8, 4, 5]));

答案 6 :(得分:0)

var arr=[1,0,-1,-2,-8,5];
var firstmin=arr[0];
var secondmin=arr[1];
for(i=0;i<=arr.length;i++) {
     if(arr[i]<firstmin){
          secondmin=firstmin;
          firstmin=arr[i];
     }
     else if(i>=1 && arr[i]<secondmin) {
         secondmin=arr[i];
     }
}

console.log(firstmin);
console.log(secondmin);

var arr = [15, 37, 9, 21, 55];
var min = Infinity, secondMin = Infinity; 
for (var i= 0; i< arr.length; i++) {
    if (arr[i]< min) {
        secondMin = min;
        min = arr[i]; 
    } else if (arr[i]< secondMin) {
        secondMin = arr[i]; 
    }
}

console.log('Smallest number: ' + min);
console.log('Second smallest number: ' + secondMin);

答案 7 :(得分:0)

var arr=[1,1,1,1,1,-1,-2];
var firstmin=arr[0];
var secondmin=arr[1];
for(i=0;i<=arr.length;i++){
  if(arr[i]<firstmin){
    secondmin=firstmin;
    firstmin=arr[i];

  }else if(i>=1 && arr[i]<secondmin) {
    secondmin=arr[i];
  }

}
console.log(firstmin);
console.log(secondmin);`

答案 8 :(得分:0)

使用三元运算符的递归方法看起来像这样。如果数组中有重复项,那么第二分钟将不重复。

例如,如果您有[1,1,2],第二分钟将是2而不是1。

function findMinimums(arr, min, secondMin, i) {
  if (arr.length === i) {
    return {
      min,
      secondMin
    }
  }
  return findMinimums(
    arr,
    min = arr[i] < min ? arr[i] : min,
    arr[i] < secondMin && min !== arr[i] ? arr[i] : secondMin,
    ++i
  )
}

const arr = [5, 34, 5, 1, 6, 7, 9, 2, 1];
console.log(findMinimums(arr, arr[0], arr[1], 0))

答案 9 :(得分:0)

let num = [4,12,99,1,3,123,5];
let sort = num.sort((a,b) => {return a-b})

console.log(sort[1])