求数据流中的中位数问题

news/2024/5/20 7:38:31 标签: 算法, 数据结构, LeetCode,

求数据流中的中位数问题

作者:Grey

原文地址:

博客园:求数据流中的中位数问题

CSDN:求数据流中的中位数问题

题目链接

LeetCode 295. Find Median from Data Stream

主要思路

要得到数据流中的中位数,在偶数的情况下,要得到上下中位数求平均,在奇数的状态下,要得到中间位置的数,这里最关键的问题就是:如何快速找到中间位置(而且是动态的)。

我们可以准备两个,一个大根,一个小根,两个分别维持在一半左右的元素,且让这两个顶始终保持中间位置的元素。这样就可以快速得到中位数需要的值了。具体操作如下:

第一个元素永远是先进大根

接下来的元素,按如下规则进入:

如果接下来的元素比大根顶元素小,进大根,否则进入小根

如果两个的大小差值已经达到2了,说明元素要向着一侧倾斜,这个时候,为了维持两个的平衡(即:始终可以拿到中位数需要的信息),从数量多的拿出一个放到数量少的,这样就让两个始终保持差值小于等于1。

此时,如果要得到中位数,通过如下规则就可以得到:

如果大根和小根数量一样,说明原始数据流是偶数个,那么直接拿出大根和小根顶元素求和再除以2就是了。

如果大根和小根数量不一样(在这一步,只能是差1),那么就取多的那个顶即为中位数。

完整代码如下

import java.util.Comparator;
import java.util.PriorityQueue;

 class MedianFinder {

        private final PriorityQueue<Integer> minHeap;
        private final PriorityQueue<Integer> maxHeap;

        public MedianFinder() {
            minHeap = new PriorityQueue<>(Comparator.comparingInt((Integer o) -> o));
            maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1);
        }

        public void addNum(int num) {
            if (maxHeap.isEmpty()) {
                maxHeap.add(num);
            } else {
                if (maxHeap.peek() >= num) {
                    maxHeap.add(num);
                } else {
                    minHeap.add(num);
                }
            }
            int maxHeapSize = maxHeap.size();
            int minHeapSize = minHeap.size();
            if (maxHeapSize - minHeapSize == 2) {
                minHeap.add(maxHeap.poll());
            } else if (minHeapSize - maxHeapSize == 2) {
                maxHeap.add(minHeap.poll());
            }
        }

        public double findMedian() {
            if (maxHeap.size() == minHeap.size()) {
                return (maxHeap.peek() + minHeap.peek()) / 2d;
            }
            if (maxHeap.size() > minHeap.size()) {
                return maxHeap.peek();
            }
            return minHeap.peek();
        }
}

更多

算法数据结构笔记


http://www.niftyadmin.cn/n/1647679.html

相关文章

C++ stat判断路径是文件还是目录

C stat判断路径是文件还是目录 1 #include <iostream>2 #include <sys/stat.h>3 4 using namespace std;5 6 void foo ( const char* path ) {7 struct stat s;8 if ( stat ( path, &s ) 0 ) {9 if ( s.st_mode & S_IFDIR ) { 10 …

yield生成器

本文链接&#xff1a;https://blog.csdn.net/qq_34246164/article/details/80960363 相同点&#xff1a;都是返回函数执行的结果 不同点&#xff1a;return 在返回结果后结束函数的运行&#xff0c;而yield 则是让函数变成一个生成器&#xff0c;生成器每次产生一个值&#xff…

找到字符串中所有字母异位词

找到字符串中所有字母异位词 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;找到字符串中所有字母异位词 CSDN&#xff1a;找到字符串中所有字母异位词 题目描述 LeetCode 438. 找到字符串中所有字母异位词 主要思路 使用滑动窗口和欠账表的机制&#…

查找元素在list中的位置以及折半查询

问题 查找某个值在list中的位置 解决思路 能够用折半查询的方法解决此问题。 解决&#xff08;Python&#xff09; #! /usr/bin/env python #coding:utf-8#折半查找某个元素在list中的位置def half_search(lst,value,left,right):length len(lst)while left<right:middle …

pip提示找不到

解决 ModuleNotFoundError: No module named pip’问题 在使用pip安装其他库时&#xff0c;提示 WARNING: You are using pip version 20.1.1; however, version 20.2.3 is available. You should consider upgrading via the ‘e:\anaconda3\python.exe -m pip install --upg…

Java SE 8 新增特性

Java SE 8 新增特性 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;Java SE 8 新增特性 CSDN&#xff1a;Java SE 8 新增特性 源码 源仓库: Github&#xff1a;java_new_features 镜像仓库: GitCode&#xff1a;java_new_features Lambda 表达式 Java…

VMware屏幕窗口自适应

点击“虚拟机”菜单栏&#xff0c;安装VMware-Tool打开命令终端 sudo apt-get install open-vm-tools

J2EE--JDBC

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主同意不得转载。https://blog.csdn.net/kanglix1an/article/details/36893005 什么是JDBC?Java语言訪问数据库的一种规范,是一套API。JDBC(Java Database Connectivity)API。即Java数据库编程接口。是一组标准的Jav…