class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (k == 0) return new int[0];
PriorityQueue<Integer> q = new PriorityQueue<>((a, b) -> b - a);
for (int a : arr) {
int t = a;
if (q.size() >= k) t = Math.min(t, q.poll());
q.add(t);
}
int[] ans = new int[k];
for (int i = 0; i < k; i++) ans[i] = q.poll();
return ans;
}
}
快排
时间复杂度 O(N) 最坏每次只确定1个元素,K 为 N,需要递归 N 次
空间复杂度 O(N) 同理,最坏递归 N 次
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
sort(arr, 0, arr.length - 1, k);
int[] ans = new int[k];
for (int i = 0; i < k; i++) ans[i] = arr[i];
return ans;
}
private void sort(int[] a, int l, int r, int k) {
if (l >= r) return;
int x = a[l + r >> 1];
int i = l - 1, j = r + 1;
while (i < j) {
do { i++; } while (a[i] < x);
do { j--; } while (a[j] > x);
if (i < j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
if (j == k - 1) return;
if (j < k - 1) sort(a, j + 1, r, k);
if (j > k - 1) sort(a, l, j, k);
}
}
def getLeastNumbers(arr, k):
ret = quickSort(arr,0,len(arr)-1,k)
print(arr)
if k == 0:
return []
else:
if ret:
return ret
else:
return arr[0:k]
# 快排(同时要剪枝)
def quickSort(arr,left,right,k):
if left > right:
return
middle = partition(arr,left,right)
# 这种情况说明排好位置的中间数和小于中间数的那一部分就是要找的答案
if k - 1 == middle:
return arr[:middle+1]
# 这种情况说明要找的前k个值在middle前面
if k - 1 < middle:
quickSort(arr,left,middle-1,k)
# 这种情况说明要找的前k个值在middle后面,middle前面的数已经都小于middle,只需要将middle后面的数排好顺序
if k - 1 > middle:
quickSort(arr,middle+1,right,k)
def partition(arr,left,right):
middle = arr[left]
x = left
y = right
while x < y:
while x <= y and middle >= arr[x]:
x += 1
while x <= y and middle <= arr[y]:
y -= 1
if x >= y:
break
temp = arr[y]
arr[y] = arr[x]
arr[x] = temp
# 跳出来的时候x>y,x为小于middle这一部分最右边的那一个,需要和middle交换一下位置顺序才对
arr[left] = arr[y]
arr[y] = middle
return y
from heapq import *
def getLeastNumbers1(arr, k):
return heapMethod(arr,k)
# 堆的方式(库中的堆是小根堆,这里需要将元素变成负数来实现大根堆)
def heapMethod(arr,k):
_arr = [-1 * arr[_] for _ in range(k)]
heapify(_arr)
for _ in range(k,len(arr)):
if -1 * arr[_] > nsmallest(1,_arr)[0]:
heappop(_arr)
heappush(_arr,-1 * arr[_])
return [-1 * _ for _ in _arr]
import java.util.PriorityQueue;
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (arr == null)
return null;
int[] res = new int[k];
PriorityQueue<Integer> queue= new PriorityQueue<>(Collections.reverseOrder());
for (int i = 0; i < arr.length; i++) {
if (i < k) {
queue.offer(arr[i]);
} else {
if (!queue.isEmpty()&&arr[i]< queue.peek()) {
queue.poll();
queue.offer(arr[i]);
}
}
}
for (int i = 0; i < k; i++) {
res[i] = queue.poll();
}
return res;
}
}
//快速排序
//时间复杂度O(N)
//空间复杂度O(logN)
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if(k == 0) return new int[0];
find(arr, 0, arr.length - 1, k - 1);
return Arrays.copyOf(arr, k);
}
public void find(int[] arr, int l, int r, int k){
//
int p = podition(arr, l, r);
if(p == k)
return;
if(p > k)
find(arr, l, p - 1, k);
else
find(arr, p + 1, r, k);
}
public int podition(int[] arr, int l, int r){
Random ran = new Random();
int p = l + ran.nextInt(r - l + 1);
swap(arr, p, l);
int i = l + 1, j = r;
while(true){
while(i <= j && arr[i] < arr[l])
i ++;
while(j >= i && arr[j] > arr[l])
j --;
if(i >= j) break;
swap(arr, i, j);
i ++;
j --;
}
swap(arr, l, j);
return j;
}
public void swap(int[] arr, int i, int j){
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
//堆
//时间复杂度O(NlogK)
//空间复杂度O(k)
class Solution2 {
public int[] getLeastNumbers(int[] arr, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
for (int i = 0; i < k; i++) {
pq.add(arr[i]);
}
for (int i = k; i < arr.length ; i++) {
if(!pq.isEmpty() && pq.peek() > arr[i]) {
pq.poll();
pq.offer(arr[i]);
}
}
int[] res = new int[k];
for(int i = 0; i < k; i ++)
res[i] = pq.poll();
return res;
}
}
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
def quick_sort(arr, l , r):
if l>=r:
return
i, j = l, r
while i < j:
while i < j and arr[j] >= arr[l]:
j -= 1
while i < j and arr[i] <= arr[l]:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[l], arr[i] = arr[i], arr[l]
quick_sort(arr, l, i-1)
quick_sort(arr, i + 1, r)
quick_sort(arr, 0, len(arr) - 1)
return arr[:k]
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (arr == null || arr.length == 0 || k == 0) {
return new int[0];
}
return quickFind(arr, 0, arr.length - 1, k);
}
int[] quickFind(int[] arr, int left, int right, int k) {
int i = partition(arr, left, right);
if (i + 1 == k) {
return Arrays.copyOf(arr, k);
}
if (i + 1 > k) {
return quickFind(arr, 0, i - 1, k);
} else {
return quickFind(arr, i + 1, right, k);
}
}
int partition(int[] arr, int left, int right) {
int pivot = arr[left];
int i = left + 1;
int j = right;
while (i < j) {
while (i <= j && arr[i] <= pivot) {
i++;
}
while (i <= j && arr[j] >= pivot) {
j--;
}
if (i >= j) {
break;
}
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
arr[left] = arr[j];
arr[j] = pivot;
return j;
}
}
共以下 22 个回答
快速排序
优先队列 实现 大顶堆
大根堆
快排
时间复杂度:期望为 O(n)
空间复杂度:期望为O(logn)
快排
大根堆
数据有范围时直接计数O(N)
快排
用的优先队列
思路:快速排序或堆
快排 时间复杂度 O(log n)
C++ getLeastNumbers(vector & arr, int k) { > q; ans;
思路: 1. 把所有数据放在大顶堆里面
2. 大顶堆的数据的个数超过k的话,就pop出大顶堆的top,也就是比较大的数
3. 然后再遍历把大顶堆里面的数据返回就好了
class Solution {
public:
vector
priority_queue<int, vector
vector
for(int i = 0; i < arr.size(); ++i) {
q.push(arr[i]);
while(q.size() > k) q.pop();
}
for(int i = 0; i < k; ++i) {
ans.push_back(q.top());
q.pop();
}
return ans;
}
};
时间:O(n),空间:O(n)
//大根堆 getLeastNumbers(vector & arr, int k) { ,cmp> que; res;
class Solution {
public:
class cmp{
public:
bool operator()(int& a,int& b){
return a<b;
}
};
vector
priority_queue<int,vector
for(int i=0;i<arr.size();++i){
que.push(arr[i]);
if(que.size()>k) que.pop();
}
vector
while(!que.empty()){
res.push_back(que.top());
que.pop();
}
return res;
};
快速排序该题时间复杂度为O(n),n+n/2+n/4+…+1 = O(n),空间复杂度由于递归深度为lgn,所有空间复杂度为O(lgn)