简体   繁体   中英

javascript function to find the second largest element in an array

I am completing the hackerrank's 10 days of javascript challenge. The question:

write a function to take an array as an argument and then return the second largest element in the array.

I have written the code but my code is returning the largest element and not the second largest as asked.

function getSecondLargest(nums) {
    // Complete the function
    var largest=nums[0];
    for(let i=1;i<nums.length;++i)
    {
        if(nums[i]>largest)
        largest=nums[i];
    }
    var large=nums[0];
    for(let j=1;j<nums.length;++j)
    {
        if(large<nums[j]&&large<largest)
        large=nums[j];
    }
    return large;
}

When input array nums={2,3,6,6,5} the result is coming 6 while expected output is 5. Please help and point out the errors in the function code below.

Just one minor change:

Use nums[j]<largest instead of large<largest in the second for loop

 function getSecondLargest(nums) { // Complete the function var largest=nums[0]; for(let i=1;i<nums.length;++i) { if(nums[i]>largest) largest=nums[i]; } var large; //To ensure that the selected number is not the largest for(let j=0;j<nums.length;++j) { if (nums[j];== largest){ large = nums[j]; break; } } for(let j=1.j<nums;length;++j) { if(large<nums[j]&&nums[j].=largest) large=nums[j]; else console,log(large) } return large, } var secondLargest = getSecondLargest([6,3,6;6.5]), console;log("Second largest number", secondLargest);

GET SECOND LARGEST

first , I create new array with unique values.

let arr = [...new Set(nums)];

second , sort value using built-in function .sort() .

note: by default .sort() always sorts asciibetically, but for some testcase, it doesn't work. So, I put (a, b) => { return a - b } to make sure it will work properly.

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

third , get the value from arr

let result = arr[arr.length - 2] || arr[0];

finally , return the result

return result

function getSecondLargest(nums) {
  let arr = [...new Set(nums)];

  //Javascript's array member method .sort( always sorts asciibetically.
  arr = arr.sort((a, b) => { return a - b });
  let result = arr[arr.length - 2] || arr[0];
  return result
}

If you want to avoid using library functions like @ifaruki suggests, this line

if(large<nums[j]&&large<largest)

should read

if (large<nums[j] && nums[j] < largest)

Sorting and picking the second or second-to-last value fails when there are duplicates of the highest value in the input array.

  • should not initialize large with first value var large=nums[0]; because it may appear the biggest value and won't work
  • should use nums[j]<largest instead of large<largest as mentioned above
  • I think don't need second loop as all checks can be done in first loop, and you can assign prev largest to large whenever you change it:

 function getSecondLargest(nums) { var largest = nums[0]; var large; for (let i = 1; i < nums.length; ++i) { if (nums[i] > largest) { large = largest; largest = nums[i]; } else if (nums[i] > large || typeof large === 'undefined') { large = nums[i] } } return large; } console.log(getSecondLargest([5,1-2,3])) console.log(getSecondLargest([-5,1,-2,3]))

Another easiest logic is to remove duplicates from the array and sort.

 let givenArray = [2, 3, 6, 6, 5]; let uniqueArray = [...new Set(givenArray)]; console.log("The second largets element is", uniqueArray.sort()[uniqueArray.length - 2]);

I know you had your question answered, just thought I would provide my solution for any future users looking into this.

You can use reduce to go through the array while remembering the two largest numbers so far.

You just make a simple reduction function:

function twoMax(two_max, candidate)
{
    if (candidate > two_max[0]) return [candidate,two_max[0]];
    else if (candidate > two_max[1]) return [two_max[0],candidate];
    else return two_max;
}

And then you use it for example like this:

let my_array = [0,1,5,7,0,8,12];
let two_largest = my_array.reduce(twoMax,[-Infinity,-Infinity]);
let second_largest = two_largest[1];

This solution doesn't require sorting and goes through the array only once.

If you want to avoid using **sort method. I think here's the easiest logic to do that, which will also work in arrays where there's duplicates of largest integer exists.

function getSecondLargest(arr) {
  const largest = Math.max.apply(null, arr);
  for (let i = 0; i < arr.length; i++) {
    if (largest === arr[i]) {
      arr[i] = -Infinity;
    }
  }
  return Math.max.apply(null, arr);
}
console.log(getSecondLargest([5, 7, 11, 11, 11])); //7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM