LeetCode 热题 100 | 堆(三)

目录

1  队列 - v2.0

2  295. 数据流的中位数

2.1  解题思路

2.2  举例说明

2.3  维持队列

2.4  求中位数

2.5  完整代码


菜鸟做题,语言是 C++

1  队列 - v2.0

排序规则果然和名字是反过来的:

// 大根堆
priority_queue<int, vector<int>, less<int>> queMin;
// 小根堆
priority_queue<int, vector<int>, greater<int>> queMax;

2  295. 数据流的中位数

2.1  解题思路

解题思路:

  • 维护两个优先队列 queMin 和 queMax
  • 前者(是大根堆)存放比中位数 midNum 小的数
  • 后者(是小根堆)存放比中位数 midNum 大的数

解题要点:

  • 维护 midNum 以进行比较
  • 保持 queMin 和 queMax 的大小基本一致

本质上就是将 nums 数组砍半,并且是按从小到大的顺序分别存储在 queMin 和 queMax 中的。到时候,中位数必定出自 queMin 或 queMax 的根元素。

2.2  举例说明

假设 nums 是 [4,5,2,1,3] 。

对于第一个数字 4,我们可以不分青红皂白地把它插入到 queMin 中,同时更新中位数为 4;对于第二个数字 5,由于 5 大于中位数,因此插入 queMax 中,同时更新中位数为 4.5;对于第三个数字 2,由于 2 小于中位数,因此插入 queMin 中。

对于第四个数字 1,由于 1 小于中位数,因此插入 queMin 中。注意:这个时候 queMin 比 queMax 多两个元素了,不满足 “砍半” 要求!因此我们需要将 4 转移到 queMax 中,同时更新中位数为 3。对于第五个数字 3,由于 3 等于中位数,因此随机插入 queMin 中。

2.3  维持队列

对 2.2 节思路的实现

void addNum(int num) {
    if (!queMin.size()) {
        queMin.push(num);
        return;
    }

    midNum = findMedian();
    if (num < midNum) {
        if (queMin.size() > queMax.size()) {
            queMax.push(queMin.top());
            queMin.pop();
        }
        queMin.push(num);
    } else {
        if (queMin.size() < queMax.size()) {
            queMin.push(queMax.top());
            queMax.pop();
        }
        queMax.push(num);
    }
}

2.4  求中位数

代码逻辑:

  • 若 queMin 和 queMax 不一样长,则中位数是较长一方的根元素
  • 若 queMin 和 queMax 一样长,则中位数等于二者根元素之和 / 2
double findMedian() {
    double ans;
    if (queMin.size() < queMax.size()) {
        ans = queMax.top();
    } else if (queMin.size() > queMax.size()) {
        ans = queMin.top();
    } else {
        ans = (queMin.top() + queMax.top()) / 2.0;
    }
    return ans;
}

2.5  完整代码
class MedianFinder {
private:
    priority_queue<int, vector<int>, less<int>> queMin;
    priority_queue<int, vector<int>, greater<int>> queMax;
    int midNum;

public:
    MedianFinder() { }
    
    void addNum(int num) {
        if (!queMin.size()) {
            queMin.push(num);
            return;
        }

        midNum = findMedian();
        if (num < midNum) {
            if (queMin.size() > queMax.size()) {
                queMax.push(queMin.top());
                queMin.pop();
            }
            queMin.push(num);
        } else {
            if (queMin.size() < queMax.size()) {
                queMin.push(queMax.top());
                queMax.pop();
            }
            queMax.push(num);
        }
    }
    
    double findMedian() {
        double ans;
        if (queMin.size() < queMax.size()) {
            ans = queMax.top();
        } else if (queMin.size() > queMax.size()) {
            ans = queMin.top();
        } else {
            ans = (queMin.top() + queMax.top()) / 2.0;
        }
        return ans;
    }
};

相关推荐

  1. leetcode100.数之和

    2024-03-25 22:18:07       30 阅读
  2. Leetcode100

    2024-03-25 22:18:07       35 阅读
  3. LeetCode100

    2024-03-25 22:18:07       9 阅读
  4. Leetcode100

    2024-03-25 22:18:07       6 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-25 22:18:07       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-25 22:18:07       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-25 22:18:07       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-25 22:18:07       20 阅读

热门阅读

  1. 7. 模型测试 - Simulink Test 功能测试

    2024-03-25 22:18:07       19 阅读
  2. QTimer

    2024-03-25 22:18:07       15 阅读
  3. LeetCode 第390场周赛个人题解

    2024-03-25 22:18:07       17 阅读
  4. VMware Workstation常见问题

    2024-03-25 22:18:07       18 阅读
  5. 教程1_图像入门

    2024-03-25 22:18:07       16 阅读
  6. 模型权重下载方法

    2024-03-25 22:18:07       19 阅读
  7. 全球化浪潮下的网络技术与安全策略

    2024-03-25 22:18:07       18 阅读
  8. 【暴刷力扣】15. 三数之和

    2024-03-25 22:18:07       17 阅读
  9. 有向图的BFS(c++题解)

    2024-03-25 22:18:07       17 阅读