The best answers to the question “Write a program to find 100 largest numbers out of an array of 1 billion numbers” in the category Dev.

__QUESTION__:

I recently attended an interview where I was asked “write a program to find 100 largest numbers out of an array of 1 billion numbers.”

I was only able to give a brute force solution which was to sort the array in O(nlogn) time complexity and take the last 100 numbers.

```
Arrays.sort(array);
```

The interviewer was looking for a better time complexity, I tried a couple of other solutions but failed to answer him. Is there a better time complexity solution?

__ANSWER__:

If this is asked in an interview, I think the interviewer probably wants to see your problem solving process, not just your knowledge of algorithms.

The description is quite general so maybe you can ask him the range or meaning of these numbers to make the problem clear. Doing this may impress an interviewer. If, for example, these numbers stands for people’s age of within a country (e.g. China),then it’s a much easier problem. With a reasonable assumption that nobody alive is older than 200, you can use an int array of size 200(maybe 201) to count the number of people with the same age in just one iteration. Here the index means the age. After this it’s a piece of cake to find 100 largest number. By the way this algo is called ** counting sort**.

Anyway, making the question more specific and clearer is good for you in an interview.

__ANSWER__:

You can keep a priority queue of the 100 biggest numbers, iterate through the billion numbers, whenever you encounter a number greater than the smallest number in the queue (the head of the queue), remove the head of the queue and add the new number to the queue.

**EDIT:**

As Dev noted, with a priority queue implemented with a heap, the complexity of insertion to queue is `O(log N)`

In the worst case you get `billion*log`

which is better than _{2}(100)`billion*log`

_{2}(billion)

In general, if you need the largest K numbers from a set of N numbers, the complexity is `O(N log K)`

rather than `O(N log N)`

, this can be very significant when K is very small comparing to N.

**EDIT2:**

The expected time of this algorithm is pretty interesting, since in each iteration an insertion may or may not occur. The probability of the i’th number to be inserted to the queue is the probability of a random variable being larger than at least `i-K`

random variables from the same distribution (the first k numbers are automatically added to the queue). We can use order statistics (see link) to calculate this probability. For example, lets assume the numbers were randomly selected uniformly from `{0, 1}`

, the expected value of (i-K)th number (out of i numbers) is `(i-k)/i`

, and chance of a random variable being larger than this value is `1-[(i-k)/i] = k/i`

.

Thus, the expected number of insertions is:

And the expected running time can be expressed as:

(`k`

time to generate the queue with the first `k`

elements, then `n-k`

comparisons, and the expected number of insertions as described above, each takes an average `log(k)/2`

time)

Note that when `N`

is very large comparing to `K`

, this expression is a lot closer to `n`

rather than `N log K`

. This is somewhat intuitive, as in the case of the question, even after 10,000 iterations (which is very small comparing to a billion), the chance of a number to be inserted to the queue is very small.

__ANSWER__:

I realized that this is tagged with ‘algorithm’, but will toss out some other options, since it probably should also be tagged ‘interview’.

What is the source of the 1 billion numbers? If it is a database then ‘select value from table order by value desc limit 100’ would do the job quite nicely – there might be dialect differences.

Is this a one-off, or something that will be repeated? If repeated, how frequently? If it is a one-off and the data are in a file, then ‘cat srcfile | sort (options as needed) | head -100’ will have you quickly doing productive work that you are getting paid to do while the computer handles this trivial chore.

If it is repeated, you would advise picking any decent approach to get the initial answer and store / cache the results so that you could continuously be able to report the top 100.

Finally, there is this consideration. Are you looking for an entry level job and interviewing with a geeky manager or future co-worker? If so, then you can toss out all manner of approaches describing the relative technical pros and cons. If you are looking for a more managerial job, then approach it like a manager would, concerned with the development and maintenance costs of the solution, and say “thank you very much” and leave if that is the interviewer wants to focus on CS trivia. He and you would be unlikely to have much advancement potential there.

Better luck on the next interview.

__ANSWER__:

You can iterate over the numbers which takes O(n)

Whenever you find a value greater than the current minimum, add the new value to a circular queue with size 100.

The min of that circular queue is your new comparison value. Keep on adding to that queue. If full, extract the minimum from the queue.