题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
python实现:
# -*- coding:utf-8 -*-
class Solution:
def GetLeastNumbers_Solution2(self, tinput, k):
# write code here
# 法1:直接排序,选取前k个最小的,最快时间复杂度O(nlogn)
# 法2:利用大顶堆,时间复杂度O(n),空间复杂度O(k),
# 方法:比堆顶小,则入堆,挤掉堆顶,最后剩下的就是最小的k个数
n = len(tinput)
if n == 0 or k > n or k <= 0:
return []
if n == k:
return sorted(tinput)
import heapq # 注意:默认是小顶堆,但我们要实现大顶堆,所以入堆时数值可以取反
heap = []
heapq.heapify(heap) # 将列表“堆化”
for num in tinput:
if len(heap)<k:
heapq.heappush(heap, -num)
else: # ==
if num < -heap[0]: # 比堆顶小
heapq.heappop(heap) # 删除堆顶
heapq.heappush(heap, -num)
return sorted([-x for x in heap]) # sorted 返回 list
# 法2:基于快排:当一次partition后返回轴枢的idx,如果idx>k,则直接看到idx后面的数,因为他们肯定
# 不是最小的k个数;如果idx==k-1,则刚好找到
# 如果idx<k,则砍掉idx前的数,并令k=k-idx
def GetLeastNumbers_Solution(self, tinput, k):
n = len(tinput)
if n == 0 or k > n or k <= 0:
return []
if n == k:
return sorted(tinput)
low, high = 0, n-1
idx = self.partition(tinput, low, high)
while idx != k-1:
if idx > k-1:
high = idx-1
else:
low = idx+1
# k = k-(idx+1)
idx = self.partition(tinput, low, high)
# 此时idx==k-1
return sorted(tinput[:k])
def partition(self, nums, low, high):
pivot = nums[low]
while low<high:
while low<high and nums[high]>=pivot:
high -= 1
nums[low] = nums[high]
# low += 1
while low<high and nums[low]<=pivot:
low += 1
nums[high] = nums[low]
high -= 1
nums[low] = pivot
return low
c++实现:
class Solution {
public:
//法1:堆
vector<int> GetLeastNumbers_Solution1(vector<int> input, int k) {
priority_queue<int> hq;//默认是大顶堆(优先队列)
vector<int> result;
if(input.empty() || k>input.size() || k<=0)
return result;
if(k==input.size()){
sort(input.begin(), input.end());
return input;
}
for(auto num : input){
if(hq.size()<k){
hq.push(num);
}else{
hq.push(num);
hq.pop();
}
}
//for(auto num:hq)
// result.push_back(num);
while(!hq.empty()){
int top = hq.top();
hq.pop();
result.push_back(top);
}
sort(result.begin(), result.end());
return result;
}
//法2:基于快排
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
//vector<int> result;
if(input.empty() || k>input.size() || k<=0)
return {};
if(k==input.size()){
sort(input.begin(), input.end());
return input;
}
int low=0, high=input.size()-1;
int idx = partition(input, low, high);
while(idx!=k-1){
if(idx>k-1){
high = idx-1;
idx = partition(input, low, high);
}else{
low = idx+1;
idx = partition(input, low, high);
}
}
//for(int i=0; i<k; i++)
// result.push_back(input[i]);
vector<int> result(input.begin(), input.begin()+k);
//sort(result.begin(), result.end());
return result;
}
int partition(vector<int> &numbers, int low, int high){
int pivot = numbers[low];
while(low<high){
while(low<high && numbers[high]>=pivot){
high--;
}
numbers[low] = numbers[high];
//numbers[low++] = numbers[high];
while(low<high && numbers[low]<=pivot){
low++;
}
numbers[high] = numbers[low];
//numbers[high--] = numbers[low];
}
numbers[low] = pivot;
return low;
}
};