力扣hot100——堆

215. 数组中的第K个最大元素

快速排序

cpp 复制代码
class Solution {
public:
    int findKthLargest(vector<int>& a, int k) {
        auto qsort = [&](this auto&& qsort, int l, int r) -> void {
            if (l == r) return;
            int i = l - 1, j = r + 1;
            int x = a[(l + r) / 2];

            /*
                如果把>改成>=,<改成<=,相同的数不就不交换,不就变成稳定的排序了?
                实际上坚决不可以这样做,因为一旦x是整个数列里最大的数,i向右移动,是找不到大于x的数的,就会越界,
                除非增加很多判断语句,要么限制x的越界,要么特判相等时不交换
            */
            while (i < j) {
                do {
                    i++;
                } while (a[i] < x);
                do {
                    j--;
                } while (a[j] > x);
                if (i < j) swap(a[i], a[j]);
            }
            /*
                注意这里边界是j,和二分法一样记住就行了,特别的细节
            */
            qsort(l, j);
            qsort(j + 1, r);
            };
        qsort(0, (int)a.size() - 1);
        return a[a.size() - k];
    }
};

线性时间选择

cpp 复制代码
class Solution {
public:
    int findKthLargest(vector<int>& a, int k) {
        auto qsort = [&](this auto&& qsort, int l, int r, int k) -> int {
            if (l == r) return a[k];
            int i = l - 1, j = r + 1;
            int x = a[(l + r) / 2];
            while (i < j) {
                do {
                    i++;
                } while (a[i] < x);
                do {
                    j--;
                } while (a[j] > x);
                if (i < j) swap(a[i], a[j]);
            }
            if (k <= j) return qsort(l, j, k);
            else return qsort(j + 1, r, k);
            };
        
        return qsort(0, (int)a.size() - 1, (int)a.size() - k);
    }
};

平均复杂度O(n):

在分解的过程当中,我们会对子数组进行划分,如果划分得到的 q 正好就是我们需要的下标,就直接返回 a[q];否则,如果 q 比目标下标小,就递归右子区间,否则递归左子区间。这样就可以把原来递归两个区间变成只递归一个区间,提高了时间效率。这就是「快速选择」算法。

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

需要注意的是,这个时间复杂度只有在 随机数据 下才成立,而对于精心构造的数据则可能表现不佳。因此我们这里并没有真正地使用随机数,而是使用双指针的方法,这种方法能够较好地应对各种数据。

347. 前 K 个高频元素

cpp 复制代码
class Solution {
public:
    vector<int> topKFrequent(vector<int>& a, int k) {
        map<int, int> mp;
        for (auto x : a) mp[x]++;
        vector<pair<int, int>> v;
        vector<int> ans;
        for (auto [x, y] : mp) {
            v.push_back({ y, x });
        }
        sort(v.begin(), v.end(), greater<>());
        for (int i = 0; i < k; i++) {
            ans.push_back(v[i].second);
        }
        return ans;
    }
};

295. 数据流的中位数

cpp 复制代码
class MedianFinder {
public:
    priority_queue<int, vector<int>, less<int>> q1; //大根堆
    priority_queue<int, vector<int>, greater<int>> q2;
    int sz;
    MedianFinder() {
        sz = 0;
    }

    void addNum(int x) {
        if (q2.empty() || x >= q2.top()) q2.push(x);
        else q1.push(x);
        sz++;
        while (q2.size() > (sz + 1) / 2) q1.push(q2.top()), q2.pop();
        while (q2.size() < (sz + 1) / 2) q2.push(q1.top()), q1.pop();
    }

    double findMedian() {
        if (sz & 1) return q2.top();
        else return (q1.top() + q2.top() + 0.0) / 2;
    }
};

对顶堆板子题,这是动态求第k大的模板(k可变化)

相关推荐
一二学长10 分钟前
异或相关的算法题
算法
暴力求解32 分钟前
c++类和对象(下)
开发语言·c++·算法
深栈1 小时前
机器学习:支持向量机
算法·机器学习·支持向量机
刘海东刘海东1 小时前
结构型智能科技理论研究(草稿)
科技·算法
C嘎嘎嵌入式开发2 小时前
(10)100天python从入门到拿捏《Python中的数据结构与自定义数据结构》
数据结构·python·算法
熬了夜的程序员2 小时前
【LeetCode】69. x 的平方根
开发语言·算法·leetcode·职场和发展·动态规划
Niuguangshuo2 小时前
音频特征提取算法介绍
算法·音视频
fengfuyao9852 小时前
基于MATLAB的匈牙利算法实现任务分配
算法·数学建模·matlab
CoovallyAIHub2 小时前
超详细链式插补 (MICE) 多元插补:机器学习模型的高级缺失数据处理
算法·机器学习·计算机视觉
明天会有多晴朗2 小时前
C语言入门教程(第6讲):函数——让程序学会“分工合作”的魔法
c语言·开发语言·算法