给定一个整数数组,找到数组中的第二大和第二小

时间:2015-09-01 21:04:07

标签: javascript arrays

我试图想出一个函数,它将取一个整数数组并输出第二个最大数字和第二个最小数字。该函数将考虑浮点数,重复数和负数。

除test2之外,两个函数都通过了以下所有测试。

var test1 = [7, 7, 12, 98, 106]
  answer1 = {2nd Min: 12, 2nd Max: 98}

var test2 = [5, 23, -112, 6, 70, 70, -112]
  answer2 = {2nd Min: 5, 2nd Max: 23}

var test3 = [-22, 22]
  answer3 = {2nd Min: 22, 2nd Max: -22}

var test4 = [10, 89, 3]
   answer = {2nd Min: 10, 2nd Max: 10}

var test5 = [10.4, -12.09, .75, 22]
  answer3 = {2nd Min: 0.75, 2nd Max: 10.4}

 /*/          \ \
 ---SOLUTION 1---
 \ \          /*/
function secondGreatLow1(arr) {
  //make copy of array because it will be spliced in the following functions
  var arrCopy = arr.slice();
  //push returned values of each function into this the answer array
  var answer = []
  answer.push(secondMin(arrCopy));
  answer.push(secondMax(arrCopy));
  return answer;
};

//helper function 1
var secondMin = function (arr){
  var arrCopy = arr.slice();
  //check length of array
  if (arr.length == 2) {
    return arr[1];
  } else {
    var min = Math.min.apply(null, arrCopy);
    arrCopy.splice(arrCopy.indexOf(min), 1);
    //check for duplicates
    for (var i = 0; i < arrCopy.length; i++) {
      if (arrCopy.indexOf(min) === -1) {
        //.apply is used for arrays
        return Math.min.apply(null, arrCopy);
      } else {
        arrCopy.splice(arrCopy.indexOf(min), 1);
        return Math.min.apply(null, arrCopy);
      }
    };
  }
};

//helper function 2
var secondMax = function (arr){
  var arrCopy = arr.slice();
  if (arr.length == 2) {
    return arr[0];
  } else {
    var max = Math.max.apply(null, arrCopy);
    arrCopy.splice(arrCopy.indexOf(max), 1);
    //check for duplicates
    for (var i = 0; i < arrCopy.length; i++) {
      if (arrCopy.indexOf(max) === -1) {
        return Math.max.apply(null, arrCopy);
      } else {
        arrCopy.splice(arrCopy.indexOf(max), 1);
        return Math.min.apply(null, arrCopy);
      }
    };
  }
};



 /*/          \ \
 ---SOLUTION 2---
 \ \         /*/
function secondGreatLow2 (numbers) {
  var arr = withoutDuplicates(numbers);
  arr.sort(function(a,b) { return a-b; });
  return arr[1] + ' ' + arr[arr.length-2];
};

// helpers
var withoutDuplicates = function(arr) {
  var out = [];
  for(var i=0; i<arr.length; i++) {
    if(i === 0 || arr[i] !== arr[i-1]) {
      out.push(arr[i]);
    }
  }
  return out;
};

8 个答案:

答案 0 :(得分:3)

In your second solution, your withoutDuplicates function appears to operate on the assumption that the list is sorted (checking for duplicates by comparing an element to the previous element); however, in secondGreatLow2, you call withoutDuplicates without performing some sort of sorting.

If you changed the order of those two lines, solution #2 looks valid assuming you don't have any floating point mismatches, ie 3.9999999999997 != 3.99999999998

答案 1 :(得分:2)

Not performance efficient for large arrays, but concise:

var a = [5, 23, -112, 6, 70, 70, -112], b = [];

// remove duplicates 
b = a.filter(function (item, pos) {
    return a.indexOf(item) == pos;
});

// sort
b.sort(function (a, b) {
    return a > b;
});

console.log(b[1]); // 2nd min:12
console.log(b[b.length-2]); // 2nd max:12

答案 2 :(得分:2)

function get_seconds(a) {
  var b = uniq(a); // remove duplicates and sort
  var l = b.length;
  return [b[1], b[l-2]];
}

Check full tests below:

var tests = {
  "case1": {
    "input": [7, 7, 12, 98, 106],
    "output": [12, 98]
  },
  "case2": {
    "input": [5, 23, -112, 6, 70, 70, -112],
    "output": [5, 23]
  },
  "case3": {
    "input": [-22, 22],
    "output": [22, -22]
  },
  "case4": {
    "input": [10, 89, 3],
    "output": [10, 10]
  },
  "case5": {
    "input": [10.4, -12.09, .75, 22],
    "output": [0.75, 10.4]
  }
};

function do_tests() {
  var res, logs = '',
    j_exp, j_res;
  $.each(tests, function(c, io) {
    j_exp = JSON.stringify(io.output);
    res = get_seconds(io.input);
    j_res = JSON.stringify(res);
    if (j_res == j_exp) {
      logs += '<div class="success">' + c + ' passed.</div>';
    } else {
      logs += '<div class="failed">' + c + ' failed.  Expected: ' + j_exp + ', Got: ' + j_res + '</div>';
    }
  });
  $("#log").html(logs);

}

function get_seconds(a) {
  var b = uniq(a);
  console.log(b, a);
  var l = b.length;
  return [b[1], b[l - 2]];
}

function uniq(a) {
  return a.sort(sortNumber).filter(function(item, pos, ary) {
    return !pos || item != ary[pos - 1];
  })
}

function sortNumber(a, b) {
  return a - b;
}
div#log {
  font-family: monospace;
}
div#log > div {
  padding: 4px;
  margin: 2px;
}
.success {
  color: green;
}
.failed {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button onclick="do_tests();">Run tests</button>

<div id="log"></div>

答案 3 :(得分:0)

这也可以,看起来更快(没有排序)。你们觉得怎么样?

var secondMax = function(arr){
    return Math.min(...arr.reduce((acc, val) =>
         (val > Math.min(...acc)) ? [Math.max(...acc), val] : acc
    , [-Infinity, -Infinity]))
}
var secondMin = function(arr){
    return Math.max(...arr.reduce((acc, val) =>
       (val < Math.max(...acc)) ? [Math.min(...acc), val] : acc
    , [Infinity, Infinity]))
}
var unique = function(arr) {
    return arr.filter((value, index, arr) =>
        arr.indexOf(value) === index
    )
}
var arr = [7, 7, 12, 98, 106, 106];
console.log(secondMin(unique(arr)));// => 12
console.log(secondMax(unique(arr)));// => 98
console.log(secondMin(arr));// => 7
console.log(secondMax(arr));// => 106

答案 4 :(得分:0)

很高兴你找到了解决方案。我正在为那些正在寻找更简单的解决方案的人发布这个。这将在O(n)时间运行。

var fl = arr[0],sl = arr[0];
var fs = Infinity,ss = Infinity;

//find the largest and smallest.
for(var i = 0;i < arr.length;i ++) {
  if(arr[i] > fl) fl = arr[i];
  if(arr[i] < fs) fs = arr[i];    
}
//let us assume smallest is second largest and vice versa.
sl = fs;
ss = fl;
//find second smallest and largest.
for(var i = 0;i < arr.length;i ++) {
  if(arr[i] < fl && arr[i] > sl) sl = arr[i];
  if(arr[i] > fs && arr[i] < ss) ss = arr[i];
}
console.log("first and second largest : ",fl,sl);
console.log("first and second smallest : ",fs,ss);

答案 5 :(得分:0)

对于第二高的数字,这是一种简单易行的方法,但问题是如果数组中存在重复,我们无法得到数字。

 function getSecondLargest(nums) {

if(nums.length<2){
    return nums;
}
var first=0;
var second=0;
for(var i=0; i<nums.length;i++)
    {
        if(nums[i]>first)
            {
                second = first;
                first = nums[i]
            }
        else(nums[i]>second && nums[i]!=first)
        {
            second = nums[i];
        }

    }
return second;
}

答案 6 :(得分:0)

如果数组包含nums = [2, 3, 6, 6, 5]之类的重复项,则以下解决方案有效,

let sortedArray = new Set(nums.sort((a, b) => b - a ));
console.log('second smallest', [...sortedArray][sortedArray.size - 2])
console.log('second largest',[...sortedArray][1]);

答案 7 :(得分:0)

用于数组的 C 程序,用于查找数组中的第二大和第二小。

#include<stdio.h>
void main()
{
    int arr[20];
    int small,big,big2,small2;
    int i,num;
    printf("Enter Number of elements:");
    scanf("%d",&num);
    printf("Enter the elements: \n");
    for(i=0;i<num;i++)
        scanf("%d",&arr[i]);//Entering elements 
    big = arr[0];//For big in array
    small = arr[0];// For small in array
    for(i=0;i<num;i++)
    {
        if(arr[i]>big)
      {
        big2 = big;
        big = arr[i];
      }
        if(arr[i]<small)
      {
        small2 = small;
        small = arr[i];
      }
    }
    printf("The biggest is %d\n",big);
    printf("The smallest is %d\n",small);
    printf("The second biggest is %d\n",big2);
    printf("The second smallest is %d\n",small2);

    }

#tej