【剑指offer】【排序】40.最小的k个数
题目链接:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/
堆排序
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
int n = arr.size();
arr.push_back(arr[0]);
for(int i = n / 2; i; i--)
down(arr, i, n);
int m = k;
vector<int> res;
while(m--)
{
res.push_back(arr[1]);
arr[1] = arr[n];
n--;
down(arr, 1, n);
}
return res;
}
void down(vector<int>& arr, int u, int n)
{
int t = u;
if(u * 2 <= n && arr[u * 2] < arr[t]) t = u * 2;
if(u * 2 + 1 <= n && arr[u * 2 + 1] < arr[t]) t = u * 2 + 1;
if(t != u) swap(arr[t], arr[u]), down(arr, t, n);
}
};
快速排序
在待排序的数组中找一个基准,将基准放到数组中合适的位置,左边比他小右边比他大;
递归对左右两边再进行同样的操作;
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
int n = arr.size();
quick_sort(arr, 0, n - 1);
vector<int> res;
for(int i = 0; i < k; i++)
res.push_back(arr[i]);
return res;
}
void quick_sort(vector<int>& arr, int l, int r){
if(l >= r) return;
int i = l - 1, j = r + 1, x = arr[l + r >> 1];
while(i < j){
do i++; while(arr[i] < x);
do j--; while(arr[j] > x);
if(i < j) swap(arr[i], arr[j]);
}
quick_sort(arr, l, j);
quick_sort(arr, j + 1, r);
}
};
归并排序
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
merge_sort(arr, 0, arr.size() - 1);
vector<int> res;
for(int i = 0; i < k; i++)
res.push_back(arr[i]);
return res;
}
void merge_sort(vector<int> &arr, int l, int r)
{
if(l >= r) return ;
int mid = l + r >> 1;
merge_sort(arr, l, mid), merge_sort(arr, mid + 1, r);
int i = l, j = mid + 1, k = 0;
vector<int> tmp(r - l + 1);
while(i <= mid && j <= r)
{
if(arr[i] < arr[j]) tmp[k++] = arr[i++];
else tmp[k++] = arr[j++];
}
while(i <= mid) tmp[k++] = arr[i++];
while(j <= r) tmp[k++] = arr[j++];
for(int i = l, k = 0; i <= r; k++, i++) arr[i] = tmp[k];
}
};
知识的价值不在于占有,而在于使用