如果对整个数组进行排序的话,前 个元素就是最小的
个数,但这样做时间成本就比较高了。
我们来介绍一下这道题目的两种比较优秀的解法。一种是利用了快排的部分思路,另一种利用了堆排的部分思路。
先介绍一下快排相关的解法。利用快排的partition函数来进行划分。如果我们的基准数划分完成了以后在第 位上的话,那基准数以及基准数前面的元素就是最小的
个数了。
class Solution {
public:
//快排思路
int partition(vector<int>&arr,int l,int r)
{
int x = arr[l];
while( l < r )
{
while(l < r && arr[r] >= x) { r--;}
arr[l] = arr[r];
while(l < r && arr[l] < x) { l++;}
arr[r] = arr[l];
}
arr[l] = x;
return l;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> ans;
int n = input.size();
if(k > n ||k<=0){return ans;}
int l = 0;
int r = n-1;
int mid = partition(input,l,r);
while(mid != k-1)
{
if(mid > k-1)
{
r = mid-1;
mid = partition(input,l,r);
}
else{
l = mid+1;
mid = partition(input,l,r);
}
}
for(int i = 0 ; i < k ; i++)
{
ans.push_back(input[i]);
}
return ans;
}
};这个题目可以借助数据结构堆在 的时间复杂度完成。并且不会修改原数组,特别适合处理海量的数据且k比较小的时候来进行。下面我们来介绍一下做法。
创建一个大根堆,限定其最多只能放 个元素。然后依次取待排序的数据
往堆里放,堆没满的话直接插入就可以了。如果堆满了的话,那目前堆顶元素就是堆中的最大值。这个时候我们来比较一下
和堆顶元素的大小。如果
比堆顶元素大的话,那就说明数据中已经有
个元素比
小了。
已经不可能属于最小的
个数了。那就直接忽略掉
继续看下一个数。如果
比堆顶元素小的话,那就将堆顶元素删除,把
插入到堆中。
堆在C++中的优先队列底层就是用堆实现的。Java和python中也可以使用优先队列。这样的话,我们直接利用优先队列就可以实现的时间复杂度获取堆顶元素,
的复杂度进行插入和删除了
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> ans ;
int N = input.size();
if(k > N||k==0){return ans;}
priority_queue<int> heap;
for(int i = 0 ; i < N ; i++)
{
if(i < k){heap.push(input[i]);}
else{
if(heap.top() > input[i])
{
heap.pop();
heap.push(input[i]);
}
}
}
while(!heap.empty())
{
ans.push_back(heap.top());
heap.pop();
}
return ans;
}
};下面再附上一份手写堆的代码。
class Solution {
public:
//堆排思路(手写堆
int heapSize;//记录堆的大小
int Left(int i){
if(i*2+1>=heapSize) return -1;
return i*2+1;
}
int Right(int i){
if(i*2+2>=heapSize) return -1;
return i*2+2;
}
void minHeapify(vector<int> & heap,int i) {
int L = Left(i);
int R = Right(i);
int maxi = i;
if(L != -1 && heap[L]>heap[i]){ maxi = L;}
if(R != -1 && heap[R]>heap[maxi]){ maxi = R;}
if(maxi != i){
swap(heap[i],heap[maxi]);
i = maxi;
minHeapify(heap,i);
}
}
void Delete(vector<int> & heap) {
swap(heap[heapSize-1],heap[0]);
heapSize--;
minHeapify(heap,0);
}
void Insert(vector<int> & heap,int n)
{
heap[heapSize] = n;
int i = heapSize;
heapSize++;
while(i!=0&& heap[i]>heap[(i-1)/2])
{
swap(heap[i],heap[(i-1)/2]);
i = (i-1)/2;
}
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> ans;
int n = input.size();
if(k>n || k<=0 ){return ans;}
heapSize = 0;
vector<int> heap(k);
for(int i = 0 ; i < n ; i++) {
if(heapSize < k) {Insert(heap,input[i]);}
else{
if(heap[0] > input[i]){
Delete(heap);
Insert(heap,input[i]);
}
}
}
return heap;
}
};
京公网安备 11010502036488号