简体   繁体   中英

What's the fastest way to find the n smallest numbers in an array?

I have a list of numbers and I need to find the n smallest of them.

This is what I have so far, but I'm sure it must be possible to do it faster and cleaner (maybe without having to sort the entire list first?):

var list = [56,34,27,4,78,12,89,1002,45,33,87,90];
var results = [];
var sorted_list = list.slice(); // fastest way to duplicate array
sorted_list.sort(function (a, b) { 
    return a - b;
});
for (var i = 0; i < n; i++) {
    // do stuff with sorted_list[i] and list
    // push the result to results
}
return results;

I think if you use a Min Heap to solve this problem, it will be faster. By that I mean

  1. Form a min heap from an array.

  2. Take out the min element and heapify.(This step you will repeat, depending upon how many items you want)

Sorting algorithm will take O(N*logN) time, while Min Heap creation(step 1) will take O(N) time and O(logN){average} will be time taken by the second step.

Note that: Heap is useful when the number of items you needs is less than N. If you repeat the step 2 N times, the total time comes out to O(N*logN) itself same as sorting.

Array.min = function( array ){
  return Math.min.apply( Math, array );
};

Source: http://ejohn.org/blog/fast-javascript-maxmin/

Thanks for the clarification. For n elements use:

Array.min = function( array, n ){
  return array.sort(function(a, b){return a-b}).slice(0, n);
};

Without sorting it can be done in this way. Basically the idea is that everytime in each iteration we will push the smallest number in an array. and will remove that number from the main array

Suppose we have an array of length 12

a=[-11,2,1,5,0,9,-8,6,-10,0,12,4];

and we have to find 4 smallest number

we can find using this function(am is the result array)

function findmin(a) {
    var item=Math.min.apply(Math, a);
    var index= a.indexOf(item);
    am.push(item);
    a.splice(index, 1);
    if(am.length<n)
    findmin(a)

}

Now suppose we have to find 9 smallest number from the array we can find(12-9=3) max number and remove it from the given array and then that will be our result.

function findmax(a) {
    var item=Math.max.apply(Math, a);
    var index= a.indexOf(item);
    am.push(item);
    a.splice(index, 1);
    if(a.length>n)
    findmax(a)

}

Here I think the complexity is nm where m is no. of element to be found and n is total no. of element.If I am not wrong. Actually i am weak in finding complexity.So please suggest if any improvement can be done.

SEE DEMO HERE

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