数据流的中位数

这篇文章展示了五种不同的方法来解决计算中位数的问题,包括暴力求解、自建堆栈、使用Python内置堆、二分堆和基于类的函数构造。每种方法都有其独特之处,涉及到了数据结构和算法的应用,以及性能优化的考虑。对于Python编程者来说,这些示例提供了关于如何处理动态中位数计算的宝贵见解。
摘要由CSDN通过智能技术生成
做题时间:2023/03/12 耗时:3+2=5个小时

1. 题目

在这里插入图片描述

2. 样例

在这里插入图片描述

3. 格式

在这里插入图片描述

4. 解题的五种思路

v1暴力求解
v2听说堆栈有用,自己构建了一个
v3使用python自带的堆栈
v4官方答案,l和r的妙用
v5在v2基础上,把解决函数构造进类


```python v1

def main():
    #code here
    global lsx
    lsx=list()
    n=int(input())
    ans=list()
    while(n>0):
        n=n-1
        a=input()
        if '+' in a:
            lsx.append(a[2])
        elif '?' in a:
            ans.append(mid())
        else:
            pass
    for i in ans:
        print(i)
def mid():
    lsx.sort()
    l=len(lsx)
    for i in lsx:
        i=int(i)
    if l%2==0:
        return (int(lsx[l//2])+int(lsx[l//2-1]))/2
    else:
        return lsx[l//2]

if __name__ == '__main__':
    main();

``


def main():
    #code here
    n=int(input())
    ans=list()
    while(n>0):
        n=n-1
        a=input()
        if '+' in a:
            insert(int(a[2]))
        elif '?' in a:
            ans.append(mid())
        else:
            pass
    for i in ans:
        print(i)
def insert(x):
    if len(array)==len(array1):
        array.append(x)
        bighead(array)
        if len(array1)==0:
            pass
        elif array[0]>array1[0]:
            array[0],array1[0]=array1[0],array[0]
    else:
        array.append(x)
        bighead(array)
        array1.append(array[0])
        del array[0]

def bighead(array):
    startfalse=len(array)//2-1
    for start in range(startfalse,-1,-1):
        big(array,start,len(array)-1)
    return array
def big(array,start,end):
    root=start
    child=2*root+1
    while child<=end:
        if child+1<=end and array[child]<array[child+1]:
            child+=1
        elif array[root]<array[child]:
            array[root],array[child]=array[child],array[root]
            root=child
            child=2*root+1
        else:
            break
def smallhead(array1):
    startfalse = len(array1) // 2 - 1
    for start in range(startfalse, -1, -1):
        big(array1, start, len(array1) - 1)
    return array1
def small(array1,start,end):
    root = start
    child = 2 * root + 1
    while child <= end:
        if child + 1 <= end and array1[child] < array1[child + 1]:
            child += 1
        elif array1[root] > array1[child]:
            array1[root], array1[child] = array1[child], array1[root]
            root = child
            child = 2 * root + 1
        else:
            break

def mid():
    if(len(array)+len(array1))%2==0:
        return (int(array[0])+int(array1[0]))/2
    else:
        return int(array[0])

if __name__ == '__main__':
    array = list()
    array1 = list()
    main();
import heapq
def main():
    #code here
    n=int(input())
    ans=list()
    while(n>0):
        n=n-1
        a=input()
        if '+' in a:
            insert(int(a[2]))
        elif '?' in a:
            ans.append(mid())
        else:
            pass
    for i in ans:
        print(i)
def insert(x):
    if len(array)==len(array1):
        heapq.heappush(array, x)
        if len(array1)==0:
            pass
        elif array[0]>-array1[0]:
            array[0],array1[0]=-array1[0],-array[0]
    else:
        heapq.heappush(array,x)
        heapq.heappush(array1, -array[0])
        heapq.heappop(array)


def mid():
    if(len(array)+len(array1))%2==0:
        return (-int(array1[0])+int(array[0]))/2
    else:
        return int(-array1[0])

if __name__ == '__main__':
    array = list()
    array1 = list()
    heapq.heapify(array1)
    heapq.heapify(array)
    main();
#include <iostream>
#include <cstring>
#include <set>
#include <vector>
#include <algorithm>
 
using namespace std;
 
multiset<int> s;
// 定义左指针和右指针
multiset<int>::iterator l = s.end(), r = s.end();
// 初始指向end
 
void addNum(int num) {
    int n = s.size();
    s.insert(num);
    // 插入第一个元素
    if(n == 0){
        l = r = s.begin();
    }
        // 元素个数由奇数个变为偶数个
    else if(n & 1){
        if(num < *l){
            l--;
        }
        else{
            r++;
        }
    }
        // 元素个数由偶数个变为奇数个
    else{
        if(num > *l && num < *r){
            l++;
            r--;
        }
        else if(num >= *r){
            l++;
        }
        else{
            r--;
            l = r;
        }
    }
}
 
double findMedian() {
    return (*l + *r) / 2.0;
}
 
int main() {
    int n;
    vector<int> num_list;
 
    cin >> n;
    while(n--) {
        getchar();
        char op = getchar();
        int num;
        if(op == '?')
            cout << findMedian() << endl;
        else if(op == '+') {
            cin >> num;
            addNum(num);
        }
    }
 
    return 0;
}

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.littlevalueMaxHeap = []
        self.bigvalueMinHeap = []
        self.maxHeapCount = 0
        self.minHeapCount = 0

    def Insert(self, num):
        if self.minHeapCount < self.maxHeapCount:
            self.minHeapCount +=1
            if num < self.littlevalueMaxHeap[0]:
                tmpNum = self.littlevalueMaxHeap[0]
                self.adjustMaxHeap(num)
                self.createMinHeap(tmpNum)
            else:
                self.createMinHeap(num)
        else:
            self.maxHeapCount+=1
            if len(self.littlevalueMaxHeap)==0:
                self.createMaxHeap(num)
            else:
               if self.bigvalueMinHeap[0]<num:
                    tmpNum=self.bigvalueMinHeap[0]
                    self.adjustMinHeap(num)
                    self.createMaxHeap(tmpNum)
               else:
                   self.createMaxHeap(num)


    def GetMedian(self):
        if self.minHeapCount<self.maxHeapCount:
            return int(self.littlevalueMaxHeap[0])
        else:
            return (int(self.littlevalueMaxHeap[0])+int(self.bigvalueMinHeap[0]))/2

    def createMaxHeap(self, num):
        self.littlevalueMaxHeap.append(num)
        tmpIndex = len(self.littlevalueMaxHeap) - 1
        while tmpIndex:
            parentIndex = (tmpIndex - 1) // 2
            if self.littlevalueMaxHeap[parentIndex] < self.littlevalueMaxHeap[tmpIndex]:
                self.littlevalueMaxHeap[parentIndex], self.littlevalueMaxHeap[tmpIndex] =\
                    self.littlevalueMaxHeap[tmpIndex], self.littlevalueMaxHeap[parentIndex]
                tmpIndex=parentIndex
            else:
                break

    def adjustMaxHeap(self,num):
        if num<self.littlevalueMaxHeap[0]:
            self.littlevalueMaxHeap[0]=num
            maxHeapLen = len(self.littlevalueMaxHeap)
            tmpIndex=0
            while tmpIndex< maxHeapLen:
                leftIndex = tmpIndex*2+1
                rightIndex = tmpIndex*2+2
                largerIndex = 0
                if rightIndex <  maxHeapLen:
                    largerIndex = rightIndex if self.littlevalueMaxHeap[leftIndex]<self.littlevalueMaxHeap[rightIndex] else leftIndex
                elif leftIndex < maxHeapLen:
                    largerIndex = leftIndex
                else:
                    break

                if self.littlevalueMaxHeap[tmpIndex] <self.littlevalueMaxHeap[largerIndex]:
                    self.littlevalueMaxHeap[tmpIndex], self.littlevalueMaxHeap[largerIndex] = self.littlevalueMaxHeap[largerIndex], self.littlevalueMaxHeap[tmpIndex]
                    tmpIndex = largerIndex
                else:
                    break


    def createMinHeap(self, num):
        self.bigvalueMinHeap.append(num)
        tmpIndex = len(self.bigvalueMinHeap) - 1
        while tmpIndex:
            parentIndex = (tmpIndex - 1) // 2
            if self.bigvalueMinHeap[tmpIndex]<self.bigvalueMinHeap[parentIndex] :
                self.bigvalueMinHeap[parentIndex], self.bigvalueMinHeap[tmpIndex] = \
                    self.bigvalueMinHeap[tmpIndex], self.bigvalueMinHeap[parentIndex]
                tmpIndex=parentIndex
            else:
                break

    def adjustMinHeap(self,num):
        if num<self.bigvalueMinHeap[0]:
            self.bigvalueMinHeap[0]=num
            minHeapLen = len(self.bigvalueMinHeap)
            tmpIndex=0
            while tmpIndex< minHeapLen:
                leftIndex = tmpIndex*2+1
                rightIndex = tmpIndex*2+2
                smallerIndex = 0
                if rightIndex <  minHeapLen:
                    smallerIndex = rightIndex if self.bigvalueMinHeap[rightIndex]<self.bigvalueMinHeap[leftIndex] else leftIndex
                elif leftIndex < minHeapLen:
                    smallerIndex = leftIndex
                else:
                    break

                if self.bigvalueMinHeap[smallerIndex] < self.bigvalueMinHeap[tmpIndex]:
                    self.bigvalueMinHeap[tmpIndex], self.bigvalueMinHeap[smallerIndex] = self.bigvalueMinHeap[smallerIndex], self.littlevalueMaxHeap[tmpIndex]
                    tmpIndex = smallerIndex
                else:
                    break


if __name__ == '__main__':
    s=Solution()
    n = int(input())
    ans = list()
    while (n > 0):
        n = n - 1
        a = input()
        if '+' in a:
            s.Insert(a[2])
        elif '?' in a:
            ans.append(s.GetMedian())
        else:
            pass
    for i in ans:
        print(i)

5. 自己许久不用python的一些小bug

(1)全局变量的引用
(2)ls的命名:不要用这个命名,和linux冲突
(3)如何定义新的函数?
(4)数据类型转换
python里最Bug的东西,无法实现批量转换,转换无用

i=int(i) for i in lsx

单个转换要小心调试
(5)//和/的区别
//取整,/取浮点数
(6)问题
样例输出是对的,但是码题集评测总是显示超时和错误
(7)思考
python对类的构建可以使得代码运行的速度更快吗?我觉得不是
官方答案里给定可以通过的版本让人觉得匪夷所思的简单,只要始终抓住那个最小的点就OK,这里采用了指针。当堆的个数由奇变偶时,要保证l指向较小的那一个,或者移动r指向较大的那一个;当堆的个数由偶变奇时,要保证l和r指向同一个数
(8)部分代码有参考其他博主,但因为网页已经删掉,所以没加进去,请谅解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值