我正在使用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);

答案 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]
那样),那么它应该<=
而不是<
。
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;
答案 2 :(得分:3)
@skyboyer提供了查找两个最小元素的最快算法。在O(n)
时间内运行的另一种类型算法是selection(在一般的comp-sci定义中,而不是在JavaScript中通常使用的方式),它将找到k
最小的元素一个数组,将元素分成较大的元素和小于k
的元素。
即使大多数分区选择算法(quickselect,Floyd-Rivest,introselect)在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])