剑指offer之数据流中的中位数

剑指offer之数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

解题思路

Partition函数的使用,奇数找中间的数,偶数找中间的两个数求平均。出了一个小bug,没意识到&==优先级的问题,导致判断偶数失效,一直WA…

Code

class Solution {
public:
    void Insert(int num)
    {
        data.push_back(num);
    }

    int Partition(int left, int right) {
        srand((unsigned)time(NULL));
        int pos = rand()%(right-left+1)+left;
        swap(data[left], data[pos]);
        int temp = data[left];
        while(left < right) {
            while(left < right && temp >= data[right]) right--;
            data[left] = data[right];
            while(left < right && temp <= data[left]) left++;
            data[right] = data[left];
        }
        data[left] = temp;
        return left;
    }
    double GetMedian()
    { 
        double result = 0;
        int length = data.size(), k1 = length>>1, k2 = -1;
        if((length&1)  == 0) {
            k2 = (length-1) >> 1;
        }
        int left = 0, right = data.size()-1;
        int partition = Partition(left, right);
        while(partition != k1) {
            if(partition > k1) {
                right = partition-1;
            } else {
                left = partition+1;
            }
            partition = Partition(left, right);
        }
        result += data[k1];
        if(k2 != -1) {
            left = 0, right = k1-1;
            partition = Partition(left, right);
            while(partition != k2) {
                if(partition > k2) {
                    right = partition-1;
                } else {
                    left = partition+1;
                }
                partition = Partition(left, right);
            }
            result += data[k2];
            result /= 2;
        }
        return result;
    }
private:
    vector<int> data;
};
  • java
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Comparator;
public class Solution {
    private Queue<Integer> stack1 = new PriorityQueue<>(new Comparator<Integer>(){
        @Override
        public int compare(Integer i1, Integer i2) {
            return i2-i1;
        }
    });
    private Queue<Integer> stack2 = new PriorityQueue<>();
    public void Insert(Integer num) {
        stack2.add(num);
        if(stack2.size() == stack1.size() + 2) {
            stack1.add(stack2.poll());
        } else if(stack1.size() != 0 && stack1.peek() > stack2.peek()) {
            stack2.add(stack1.poll());
            stack1.add(stack2.poll());
        }
    }
// 1 5 2 6 3
    public Double GetMedian() {
        double mid = 0.0;
        mid = stack2.peek();
        if(stack1.size() == stack2.size()) {
            mid += stack1.peek();
            mid /= 2.0;
        }
        return mid;
    }
}
  • 评论区还是精彩
//链接:https://www.nowcoder.com/questionTerminal/9be0172896bd43948f8a32fb954e1be1
//来源:牛客网

class Solution {
    priority_queue<int, vector<int>, less<int> > p;
    priority_queue<int, vector<int>, greater<int> > q;
     
public:
    void Insert(int num){
        if(p.empty() || num <= p.top()) p.push(num);
        else q.push(num);
        if(p.size() == q.size() + 2) q.push(p.top()), p.pop();
        if(p.size() + 1 == q.size()) p.push(q.top()), q.pop();
    }
    double GetMedian(){ 
      return p.size() == q.size() ? (p.top() + q.top()) / 2.0 : p.top();
    }
};

总结

	 if((length&1)  == 0) 

这句,由于&的优先级小于==,所以要加上括号。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值