力扣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可变化)

相关推荐
破-风3 小时前
leetcode-------mysql
算法·leetcode·职场和发展
自不量力的A同学7 小时前
如何利用人工智能算法优化知识分类和标签?
人工智能·算法·分类
CodeJourney.8 小时前
PyTorch不同优化器比较
人工智能·pytorch·算法·能源
winner88818 小时前
对比学习损失函数 - InfoNCE
学习·算法·对比学习·infonce
南宫生8 小时前
力扣-数据结构-12【算法学习day.83】
java·数据结构·学习·算法·leetcode
KeyPan8 小时前
【数据结构与算法:五、树和二叉树】
java·开发语言·数据结构·人工智能·算法·机器学习·计算机视觉
WBingJ8 小时前
机器学习基础-贝叶斯分类器
人工智能·算法·机器学习
Lenyiin9 小时前
第431场周赛:最长乘积等价子数组、计算字符串的镜像分数、收集连续 K 个袋子可以获得的最多硬币数量、不重叠区间的最大得分
c++·算法·leetcode·周赛·lenyiin
行知SLAM9 小时前
第0章 机器人及自动驾驶SLAM定位方法全解析及入门进阶学习建议
人工智能·算法·机器人·自动驾驶
起名方面没有灵感11 小时前
力扣23.合并K个升序链表
java·算法