Question: Enter n integers and output the smallest k integers.
For example, if you enter the 8 numbers 1, 2, 3, 5, 6, 7, and 8, the minimum four digits are 1, 2, 3, and 4.
Analysis: the simplest way to solve this problem is to sort the input n integers so that the number of K at the top is the minimum number of K. The time complexity of this approach is O (nlogn ). We try to find a faster solution.
We can open up an array with a length of K. Each time a number is read from the input n integers. If the number of inserted elements in the array is less than K, the read integer is directly put into the array. Otherwise, the array with the length of K is full and cannot be inserted into the array. It can only be replaced. If the integer to be read is smaller than the maximum value of K integers in the array, replace the maximum value with the integer to be read; if the integer to be read is larger than the maximum value of K integers in the array, the integer to be read cannot be one of the smallest k integers. This approach is equivalent to sorting K integers, so time complexity can be reduced to O (N + nlogk ). Generally, K is much smaller than N, so this method is better than the previous idea.
This is the fastest solution I can come up. But from the perspective of giving the interviewer a better impression, we can further write the code more beautifully. From the above analysis, when the array with a length of K is full, if you need to replace it, each replacement is the maximum value in the array. In common data structures, the data structure that can obtain the maximum value in O (1) Time is the maximum heap. Therefore, we can use heap instead of array.
In addition, you need to write a certain amount of code for the largest heap. We don't need to re-invent the wheel, because our predecessors have already invented the wheel. Similarly, set and Multiset in STL provide a good heap implementation for us. We can use them. I am a little lazy and leave a good impression on the interviewer who is familiar with STL. Why not?
Reference code:
#include <set>#include <vector>#include <iostream>using namespace std;typedef multiset<int, greater<int> > IntHeap;///////////////////////////////////////////////////////////////////////// find k least numbers in a vector///////////////////////////////////////////////////////////////////////void FindKLeastNumbers( const vector<int>& data, // a vector of data IntHeap& leastNumbers, // k least numbers, output unsigned int k ){ leastNumbers.clear(); if(k == 0 || data.size() < k) return; vector<int>::const_iterator iter = data.begin(); for(; iter != data.end(); ++ iter) { // if less than k numbers was inserted into leastNumbers if((leastNumbers.size()) < k) leastNumbers.insert(*iter); // leastNumbers contains k numbers and it‘s full now else { // first number in leastNumbers is the greatest one IntHeap::iterator iterFirst = leastNumbers.begin(); // if is less than the previous greatest number if(*iter < *(leastNumbers.begin())) { // replace the previous greatest number leastNumbers.erase(iterFirst); leastNumbers.insert(*iter); } } }}