Leetcode题解 剑指 Offer 40. 最小的k个数
PROBLEM
难度 简单
MY ANSWER
使用大顶堆,遍历到比堆顶小的元素时,出堆并将元素插入。priority_queue默认就为大顶堆,若构造小顶堆取相反数即可。时间复杂度为O(nlogk),空间复杂度O(k)。
class Solution { |
BETTER SOLUTION
快排思路,划分直到pivot等于k为止,返回前面k个数。平均时间复杂度O(n),最坏情况下时间复杂度为O(n^2),空间复杂度O(logn)。
class Solution { |
SUMMARY
堆模板:
//小顶堆
vector<int> arr;
int heapsize;
void init() {
arr.push_back(INT_MIN); //0存储最小值标志,堆从1开始
heapsize = 0;
}
void push(int x) { //加到末尾,上滤
int i;
arr.push_back(x);
for(i = ++heapsize; arr[i/2] > x; i /= 2) {
arr[i] = arr[i / 2];
}
arr[i] = x;
}
void pop() { //最尾部节点放到堆顶,下滤
int i, child;
int min, last;
min = arr[1];
last = arr[heapsize--];
for(i = 1; i * 2 <= heapsize; i = child) {
child = i * 2;
if(child != heapsize && arr[child+1] < arr[child]) {
child++;
}
if(last > arr[child]) {
arr[i] = arr[child];
}
else {
break;
}
}
arr[i] = last;
arr.pop_back();
}
void buildheap(vector<int> tmp) { //从第一个有儿子的节点开始逐个下滤
arr = tmp;
arr.insert(arr.begin(), INT_MIN);
heapsize = tmp.size();
for(int i = heapsize / 2; i > 0; i--) {
int node, child;
node = arr[i];
int j;
for(j = i; j * 2<= heapsize; j = child) {
child = j * 2;
if(child != heapsize && arr[child+1] < arr[child]) {
child++;
}
if(node > arr[child]) {
arr[j] = arr[child];
}
else {
break;
}
}
arr[j] = node;
}
}
int top() {
return arr[1];
}快排模板:
void quickSort(vector<int>& arr, int l, int r) {
// 子数组长度为 1 时终止递归
if (l >= r) return;
// 哨兵划分操作(以 arr[l] 作为基准数)
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]);
// 递归左(右)子数组执行哨兵划分
quickSort(arr, l, i - 1);
quickSort(arr, i + 1, r);
}
};
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Jayce's Blog!
评论