admin管理员组

文章数量:1287933

I am trying to e up with a function that will take an array of integers and output the 2nd highest number and the 2nd smallest number. The function will take into account floats, duplicates, and negative numbers.

Two functions pass all the tests below except for 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;
};

I am trying to e up with a function that will take an array of integers and output the 2nd highest number and the 2nd smallest number. The function will take into account floats, duplicates, and negative numbers.

Two functions pass all the tests below except for 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;
};
Share Improve this question edited Sep 1, 2015 at 21:45 Crystal asked Sep 1, 2015 at 21:04 CrystalCrystal 1,5052 gold badges24 silver badges35 bronze badges 3
  • How e 2nd Max: 12 and not 98 in [7, 7, 12, 98, 106]? – Vidul Commented Sep 1, 2015 at 21:10
  • oh that's a typo good catch! Updated! – Crystal Commented Sep 1, 2015 at 21:12
  • @xgrioux What is the question? You must state it in question format explicitly – Thomas Commented Sep 1, 2015 at 21:33
Add a ment  | 

9 Answers 9

Reset to default 3

In your second solution, your withoutDuplicates function appears to operate on the assumption that the list is sorted (checking for duplicates by paring 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

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

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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>

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

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

This would also work and it appears do be faster (no sorting). What do you guys think?

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

Glad you have found the solution.I am posting this for those who are searching for a simpler solution.This would run on O(n) time.

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);

This is an easy and simple method for a second highest number but the problem is we could not get a number if there have duplicate exists in the array.

 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;
}

If array contains duplicates like nums = [2, 3, 6, 6, 5], the below solution works,

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

C program for arrays to find second largest and second smallest in a array.

#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

let ar = [1,4,76,80,90,3,6,82];

var big = 0,sbig=0;
for(let i=0; i<ar.length;i++){
  if(big < ar[i]) {
    sbig = big;
    big = ar[i]
    continue; 
  }
  if(sbig < ar[i]) {
    sbig = ar[i];
  }
}
console.log(sbig,big);

本文标签: