排序函数:
c++
vector 排序
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> res(k, 0); // vector 初始化
sort(arr.begin(), arr.end()); // 小到大排序
int c=0;
for (auto i:arr){
if(c<k){
res.push_back(i);
c++;
}
}
return res;
}
};
python
list 排序
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
arr = sorted(arr) # 大到小排序sorted(a,reverse=True)
res = []
c=0
for i in arr:
if c<k:
res.append(i)
c += 1
return res
维护一个k个最小数的堆:
最小最大堆用优先队列实现
优先队列 c++
1. 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。
2. 在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出。
3. 优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序
// c++默认是大顶堆 大的值有最高优先级
priority_queue <int,vector<int>,less<int> >q; //降序队列,大顶堆
priority_queue <int> q; // //降序队列,大顶堆
priority_queue <int,vector<int>,greater<int> > q; //升序队列,小顶堆
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> res(k, 0);
if (k == 0) { // 排除 0 的情况
return res;
}
//queue <int> que; // 普通队列
priority_queue <int> que; // 优先队列,另外定义优先级,优先级高的先出
int n = arr.size();
for(int i = 0; i < k; i++) {
que.push(arr[i]);
}
for(int i=k; i<n; i++){ // 优先队列每次进新数都会内部排序,对顶是最大的数,有最高优先级
if (que.top() > arr[i]) {
que.pop(); // 大的数弹出
que.push(arr[i]);
}
}
for (int i = 0; i < k; i++) { //队列中数弹出给vector返回
res[i] = que.top();
que.pop();
}
return res;
}
};
python
c++ 默认最大堆,即优先队列中对顶是最大数,大到小排序
python 默认最小堆,即优先队列中对顶是最小数,小到大排序
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
if k == 0:
return []
hp = [-x for x in arr[:k]] #列表前k个数取相反数,则python优先队列,队顶最小数其实是取相反数前的最大数
heapq.heapify(hp) # 将列表hp原地转换成堆 import heapq heap[0]总是最小的那个元素
for i in range(k, len(arr)): # 从第k个数开始与队顶比较
if -hp[0]>arr[i]: # 取反才是原来的数
heapq.heappop(hp) # hp 弹出队顶
heapq.heappush(hp, -arr[i]) # arr[i]取反加入堆 (进入后堆将内部排序)
res = [-x for x in hp]
return res
快排
c++
class Solution {
private:
void quickSort(vector<int>& arr, int l, int r){
// 子数组长度为 1 时终止递归
if (l >= r){
return;
}
// 哨兵划分操作(以 arr[l] 作为基准数)
int i = l, j = r; // i j 左右哨兵位置
while (i < j){
while (i < j && arr[j] >= arr[l]) j--; // 右指针找到比基准数更小的(必须右边的哨兵先动)
while (i < j && arr[i] <= arr[l]) i++; // 作指针找到比基准数更大的
swap(arr[i], arr[j]); // 交换
}
swap(arr[i], arr[l]);
// 快排完成
// 递归左(右)子数组执行哨兵划分
quickSort(arr, l, i - 1); // 左子数组
quickSort(arr, i + 1, r); // 右子数组
}
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
quickSort(arr, 0, arr.size() - 1); // 快排递归函数(数组,起始,终止)
vector<int> res;
res.assign(arr.begin(), arr.begin() + k); // 区间[first,last)的元素赋值到当前的vector容器
return res;
}
};
python
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
def quick_sort(arr, l, r):
# 子数组长度为 1 时终止递归
if l >= r:
return
# 哨兵划分操作(以 arr[l] 作为基准数)
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] # swap(arr[i], arr[l]); c++
arr[i], arr[l] = arr[l], arr[i] # swap(arr[i], arr[l])
# 左右子数组递归开始,此时位置i是分界点
quick_sort(arr,l,i-1)
quick_sort(arr,i+1,r)
quick_sort(arr, 0, len(arr) - 1) # 调用递归函数 全排列arr
return arr[:k] # arr是已经从小到大排序的,返回前k个
基于快速排序的数组划分
c++
class Solution {
private:
vector<int> quickSort(vector<int>& arr, int k, int l, int r){ // 函数返回前k个排序
int i = l, j = r;
while (i < j) {
while (i < j && arr[j] >= arr[l]) j--;
while (i < j && arr[i] <= arr[l]) i++;
swap(arr[i], arr[j]);
}
swap(arr[i], arr[l]);
if (i > k) return quickSort(arr, k, l, i - 1); // k在分界点i左边,只快排左子数组(下一个分界点左移动一个,以递归找到位置k)
if (i < k) return quickSort(arr, k, i + 1, r); // k在分界点i右边,只快排右子数组(下一个分界右移动一个,以递归找到位置k)
vector<int> res;
res.assign(arr.begin(), arr.begin() + k); // 前k个赋值给res
return res;
}
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
if (k >= arr.size()){
return arr; // 若 k 大于数组长度,则直接返回整个数组;
}
return quickSort(arr, k, 0, arr.size() - 1); // 快排
}
};
python
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
if k >= len(arr): return arr # 若 k 大于数组长度,则直接返回整个数组;
def quick_sort(l, r):
# 哨兵划分操作(以 arr[l] 作为基准数)
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] # swap(arr[i], arr[l]); c++
arr[i], arr[l] = arr[l], arr[i] # swap(arr[i], arr[l])
if i<k: return quick_sort(i+1,r) # k比分界点i右,下一次排序右边界右移
if i>k: return quick_sort(l,i-1) # k比分界点i左,下一次排序右边界左移
return arr[:k] # 递归终止条件:i==k
return quick_sort(0, len(arr) - 1)