题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路1:先对数组从小达到进行排序,输出前k个数。快速排序,时间复杂度:O(nlogn)。
代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int len = input.size();
int low=0;
int high=len-1;
vector<int> res;
if(len<=0 || k>len) return res;
quick_sort(input, low, high);
for(int i=0; i<k; i++)
res.push_back(input[i]);
return res;
}
void quick_sort(vector<int>& output, int start, int end)
{
int index=start;
int i=start;
int j=end;
int base=output[index];
while(i<j)
{
while(i<j && output[j]>=base) j--;
output[i]=output[j];
while(i<j && output[i]<=base) i++;
output[j]=output[i];
}
index = i;
output[index] = base;
if(i-start>1) quick_sort(output, start, i-1);
if(end-j>1) quick_sort(output, j+1, end);
}
};
思路2:使用partition函数(进行一次快速排序,用哨兵数分割数组中的数据),时间复杂度:O(n)
代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
int high = input.size()-1;
int low = 0;
if((high+1)<k || k<=0 || input.empty()) return res;
int index = partition(input,low,high);
for(int i=0; i<k; i++)
{
while(index!=i)
{
if(index<k) low=index+1;
else high=index-1;
index = partition(input,low,high);
}
res.push_back(input[index]);
}
return res;
}
int partition(vector<int>& nums, int low, int high)
{
if(low<0 || high>nums.size() || low>high) return -1;
if(low==high) return low;
int base=nums[low];
while(low<high)
{
while(low<high && nums[high]>=base) high--;
nums[low]=nums[high];
while(low<high && nums[low]<=base) low++;
nums[high]=nums[low];
}
nums[low]=base;
return low;
}
};
思路3:小顶堆(优先队列),时间复杂度:O(nlog(k)).
STL中的优先队列默认是大顶堆,这里生成小顶堆即可。
priority_queue的用法
模板申明带3个参数:priority_queue<Type, Container, Functional>,其中Type 为数据类型,Container为保存数据的容器,Functional 为元素比较方式。Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector,大顶堆(降序),队头元素最大。
c.top() | 返回队列头部数据 |
c.push(elem) | 在队列尾部增加elem数据 |
c.pop() | 队列头部数据出队 |
代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(k<=0 || k>input.size()) return res;
priority_queue<int> q; // STL中的优先队列默认是大顶堆
unsigned int i=0;
while(i<input.size())
{
q.push(input[i]);
if(q.size()>k) q.pop();
i++;
}
while(!q.empty())
{
res.push_back(q.top()); // C语言中的top()可返回顶部元素的值,也可返回顶部元素的指针,程序员自行设计; C++的STL中top()返回的是顶部的值
q.pop();
}
return res;
}
};