【问题标题】:How do I get the second largest element from an array in javascript [closed]如何从javascript中的数组中获取第二大元素[关闭]
【发布时间】:2021-05-26 19:11:15
【问题描述】:

我有一个这样的整数数组:

arr[20,120,111,215,54,78];

我需要一个以数组为参数并返回该数组的第二大元素的函数。

【问题讨论】:

  • 你有没有尝试过?
  • 注意:这不是一个整数数组,那是一个字符串数组。如果您不正确地比较这些元素,您可能会得到“意外”的结果,因为字符串使用词法排序。例如,'20' < '120' === false20 < 120 === true
  • 到底谁会赞成这样的零努力问题?这是投票环的工作吗?
  • 我发现这个(ajaybadgujar.com/…) 解决方案非常有用,而且复杂度极低
  • 最简单的解决方案之一是:- arr = [20,120,111,215,54,78];让 secondLargest = arr.sort(function(x,y) { return y-x} )[1];如果您想采用传统方式;- arr = [20,120,111,215,54,78]; max=arr[0] max2=arr[0] for(let i=0; i

标签: javascript


【解决方案1】:

最直接的实现方式,在不修改原始数组的情况下,迭代并跟踪最大和次大:

function nextBiggest(arr) {
  let max = -Infinity, result = -Infinity;

  for (const value of arr) {
    const nr = Number(value)

    if (nr > max) {
      [result, max] = [max, nr] // save previous max
    } else if (nr < max && nr > result) {
      result = nr; // new second biggest
    }
  }

  return result;
}

const arr = ['20','120','111','215','54','78'];
console.log(nextBiggest(arr));

【讨论】:

  • +1 我很惊讶人们在 15 分钟内对数组进行排序,而不是只执行一次传递。
  • 这也有它的问题,有两个相等的“最高值”。我想这仍然是一个定义问题,但任何关于此要求的算法都应返回 5 以获得 [5,10,10] 列表。
  • @jAndy 感谢您发现明显的疏忽 :) 已修复。
  • @davin 大多数情况下,在 JavaScript 中,您并不真正关心您的代码是否需要 10 毫秒而不是 3 毫秒,但您关心的是应用程序的简单性。我不是说这是一个不好的答案,它很好,但是这里的 cmets 对性能的关注可能被夸大了。
  • @dystroy 这种方法的简单性还可以轻松满足多个相同的最大值:)
【解决方案2】:

原答案

var secondMax = function (){ 
    var arr = [20, 120, 111, 215, 54, 78]; // use int arrays
    var max = Math.max.apply(null, arr); // get the max of the array
    arr.splice(arr.indexOf(max), 1); // remove max from the array
    return Math.max.apply(null, arr); // get the 2nd max
};

demo

更新 1

正如 davin 所指出的,性能可以通过不进行拼接但暂时-Infininty 替换最大值来提高:

var secondMax = function (arr){ 
    var max = Math.max.apply(null, arr), // get the max of the array
        maxi = arr.indexOf(max);
    arr[maxi] = -Infinity; // replace max in the array with -infinity
    var secondMax = Math.max.apply(null, arr); // get the new max 
    arr[maxi] = max;
    return secondMax;
};

无论如何,恕我直言,最好的算法是 Jack 的。 1 次通过,转换为数字。 我的很短,使用内置方法,只是想提供它作为替代方案,以展示您可以实现目标的所有不同方式。

更新 2

具有多个值的边缘情况。

正如 cmets 指出的那样:如果我们有一个像 [3, 3, 5, 5, 5, 4, 4] 这样的数组,这个解决方案“不起作用”。 另一方面,我们认为“第二大元素”也是一个解释问题。 在示例中,我们有:

  1. 在索引处具有最大值 (5) 的 3 个元素:2,3,4
  2. 在索引处具有第二大值 (4) 的 2 个元素:5,6
  3. 2 个元素在索引处具有第二个最小值 (3):1,2

第二大元素可以解释为:

  1. 第二个(最大元素) - 索引 3 处的 5 - 假设存在顺序,并且我们的目标是唯一值
  2. (第二大)元素 - 索引 5 处的 4 - 假设存在顺序,并且我们的目标是唯一值

【讨论】:

  • 目前唯一正确的O(n) 解决方案。
  • @davin 它修改了数组。
  • @Jack,很容易通过用-Infinity 就地替换然后恢复来克服。与使用O(n) 空间的其他方法相比,这也将更快并确保全面的O(1) 空间复杂度。
  • @davin 我不会称其为改进......你已经看到了 my 的答案,对吧? :) -Infinity 虽然是个好点..
  • 它也会在[5,3,20,9,20]之类的列表中“失败”。
【解决方案3】:

最简单的解决方案是排序:

// here's your array :
var stringArray = new Array('20','120','111','215','54','78');

// let's convert it to a real array of numbers, not of strings :
var intArray = stringArray.map(Number);

// now let's sort it and take the second element :
var second = intArray.sort(function(a,b){return b-a})[1]; 

如果您不想要最简单但最快的(您可能不需要它),那么您必须编写 for 循环并在循环时存储两个最大的元素。

【讨论】:

  • +1 表示.map( Number );
  • 如果列表中有两个相同的数字,这将失败。
  • @dystroy 我认为 Harry 的意思是,如果有两个 '215' 值,它会给出错误的第二大值。
  • @DenysSéguret 不适用于输入 like-> ['20','120​​','111','215','54','54']
  • 如果有重复,只需在排序前执行intArray = [...new Set(intArray)];
【解决方案4】:

先倒序排列,然后得到第二个元素:

['20','120','111','215','54','78'].sort(function(a, b) { return b - a; })[1];
// '120'

显然也适用于字符串。

【讨论】:

  • +1 提到转换为数字并不是排序所必需的。
  • @dystroy,演员阵容是严格需要的,没有明确需要。这个方法确实转换为Number,只是它隐式地转换了。
  • @davin 我当然知道,我说的是添加中间步骤。
  • 当数组中有重复的数字时,这将失败,例如。 [2, 3, 6, 6, 5] 预期的输出是 5,但是使用这行代码你会得到 6
  • 对于数组中的重复值,这没有通过预期的算法
【解决方案5】:

对数组进行排序,然后返回第二个索引。

var arr = ['20','120','111','215','54','78'];

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

console.log(arr[1]);

【讨论】:

  • 如果数组中有重复项,这将失败。
【解决方案6】:

你可以试试这个:

function second_highest(arr)
{
  var second_highest = arr.sort(function(a, b) { return b - a; })[1];
  return second_highest;

}

【讨论】:

  • 请注意 sort 将对原始数组进行排序,它不会复制。因此,任何依赖于项目先前排序的东西都可能会损坏。
【解决方案7】:

将您的数组从小到大排序,然后用.length-2从末尾开始抓取第二个

var myArray =['20','120','111','215','54','78'];
var secondLargest = myArray.sort(function(a,b){return a - b})[myArray.length-2];
alert(secondLargest); //120;

【讨论】:

  • 如果最小的数字重复多次,则失败,哈哈
猜你喜欢
  • 2019-08-15
  • 2020-04-05
  • 1970-01-01
  • 2013-04-19
  • 2013-02-05
  • 2017-03-06
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
相关资源
最近更新 更多