Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimize- get third largest num in array

So, I was working on this challenge to return the third largest number in an array. I had got it worked out until I realized that I must account for repeat numbers. I handled this by adding 3 layers of for loops with variables i, j, and k. You'll see what I mean in the code. This is not terribly efficient or scalable.

My question is, how can I optimize this code? What other methods should I be using?

function thirdGreatest (arr) {
    arr.sort(function(a, b) {
        if (a < b) {
            return 1;
        } else if (a > b) {
            return -1;
        } else {
            return 0;
        }
    });

    for ( var i = 0; i < arr.length; i++) {
        for (var j = 1; j < arr.length; j++) {
            for (var k = 2; k < arr.length; k++) {
                if (arr[i] > arr[j]) {
                    if (arr[j] > arr[k]) {
                        return arr[k];
                    }

                }
            }
        }
    }


}

console.log(thirdGreatest([5, 3, 23, 7,3,2,5,10,24,2,31, 31, 31])); // 23
console.log(thirdGreatest([5, 3, 23, 7,3,2,5,10,24,2,31])) // 23
console.log(thirdGreatest([5, 3, 7, 4])); // 4
console.log(thirdGreatest([2, 3, 7, 4])); // 3
like image 476
Alfonso Giron Avatar asked May 18 '16 00:05

Alfonso Giron


People also ask

How do you find the 3 Maximum elements in an array?

Solution Approachif (arr[i] > max) -> max3 = max2, max2 = max , max = arr[i]. else if (arr[i] > max2) -> max3 = max2, max2 = arr[i]. else if (arr[i] > max3) -> max3 = arr[i]. At the end of the loop, we will print all three values.


2 Answers

Since you already sorted the array, it seems like you should be fine iterating over the list and keep track of the numbers you have already seen. When you have seen three different numbers, return the current one:

var seen = [arr[0]];

for (var i = 1; i < arr.length; i++) {
  if (arr[i] !== seen[0]) {
    if (seen.length === 2) {
      return arr[i];
    }
    seen.unshift(arr[i]);
  }
}

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

    var seen = [arr[0]];
    
    for (var i = 1; i < arr.length; i++) {
      if (arr[i] !== seen[0]) {
        if (seen.length === 2) {
          return arr[i];
        }
        seen.unshift(arr[i]);
      }
    }
}

console.log(thirdGreatest([5, 3, 23, 7,3,2,5,10,24,2,31, 31, 31])); // 23
console.log(thirdGreatest([5, 3, 23, 7,3,2,5,10,24,2,31])) // 23
console.log(thirdGreatest([5, 3, 7, 4])); // 4
console.log(thirdGreatest([2, 3, 7, 4])); // 3

Note: You can simplify the sort callback to

arr.sort(function(a, b) {
  return b - a;
});
// With arrow functions:
// arr.sort((a, b) => b - a);

The callback has to return a number that is larger, smaller or equal to 0, it doesn't have to be exactly -1 or 1.

like image 123
Felix Kling Avatar answered Sep 27 '22 18:09

Felix Kling


A one-"line"r using Set to remove duplicates

Array.from(new Set(arr)).sort(function(a, b) {
    return b - a;
})[2];

Set now has reasonable browser support

like image 37
Eric Avatar answered Sep 27 '22 19:09

Eric