zoukankan      html  css  js  c++  java
  • 295. Find Median from Data Stream

    • 题目思路

    • 代码实现

    • 1 code1
    class MedianFinder
    {
    public:
    	/** initialize your data structure here. */
    	MedianFinder()
    	{
    		maxheapsize = 0;
    		minheapsize = 0;
    	}
    
    	void addNum(int num)
    	{
    		//1 和大根堆的堆顶元素进行比较
    		//比大根堆的堆顶元素大--->将元素插入的小根堆--->插入过程发现heapsize的差大于1--->小根堆弹出堆顶元素给大根堆,小根堆插入新元素
    		//比大根堆的堆顶元素小--->将元素插入到大根堆--->插入过程发现heapsize的差大于1--->大根堆弹出堆顶元素给小根堆,大根堆插入新元素
    		if (maxheapsize == 0)
    		{
    			maxheap.push_back(num);
    			make_heap(maxheap.begin(), maxheap.end());
    			maxheapsize++;
    		}
    		else
    		{
    			if (num > maxheap[0])  //num 比大根堆的堆顶大
    			{
    
    				if (minheapsize + 1 - maxheapsize > 1)
    				{
    					//先弹出 在插入
    					pop_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					auto smallest = minheap.back();
    					minheap.pop_back();
    					minheapsize--;
    
    					//最大堆插入
    					maxheap.push_back(smallest);
    					push_heap(maxheap.begin(), maxheap.end());
    					maxheapsize++;
    
    					//最小堆插入
    					minheap.push_back(num);
    					push_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					minheapsize++;
    				}
    				else
    				{
    					//将元素插入的小根堆
    					minheap.push_back(num);
    					push_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					minheapsize++;
    				}
    			}
    			else  // num <= 大根堆的堆顶
    			{
    				if (maxheapsize + 1 - minheapsize > 1)
    				{
    					//大根堆弹出堆顶元素给小根堆,大根堆插入新元素
    					//先弹出 在插入
    					pop_heap(maxheap.begin(), maxheap.end());
    					auto largest = maxheap.back();
    					maxheap.pop_back();
    					maxheapsize--;
    
    					//最小堆插入
    					minheap.push_back(largest);
    					push_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					minheapsize++;
    
    					//最大堆插入
    					maxheap.push_back(num);
    					push_heap(maxheap.begin(), maxheap.end());
    					maxheapsize++;
    				}
    				else
    				{
    					//将元素插入大根堆
    					maxheap.push_back(num);
    					push_heap(maxheap.begin(), maxheap.end());
    					maxheapsize++;
    				}
    			}
    		}
    
    
    	}  //end void addNum(int num) 
    
    	double findMedian()
    	{
    		if (maxheapsize == 1 && minheapsize == 0)
    		{
    			return maxheap[0];
    		}
    		if ((maxheapsize + minheapsize) % 2 == 0)
    		{
    			//当前两个堆中的元素共偶数个
    			return double(maxheap[0] + minheap[0]) / 2;
    		}
    		else
    		{
    			return minheap[0];
    		}
    	}
    private:
    	vector<int> maxheap;  //大根堆
    	vector<int> minheap;  //小根堆
    	int maxheapsize;
    	int minheapsize;
    
    };
    
    • 2 code2
    class MedianFinder
    {
    public:
    	/** initialize your data structure here. */
    	MedianFinder()
    	{
    		maxheapsize = 0;
    		minheapsize = 0;
    	}
    
    	void addNum(int num)
    	{	
    		if (minheapsize == 0)
    		{
    			minheap.push_back(num);
    			make_heap(minheap.begin(), minheap.end(), std::greater<>{});
    			minheapsize++;
    		}
    		else
    		{
    			if (num <= minheap[0])  //num <= 小根堆的堆顶
    			{
                    //应该插入大根堆 下面就插入大根堆的情况进行讨论
    
    				if (maxheapsize + 1 - minheapsize > 1)
    				{
    					//大根堆弹出堆顶元素给小根堆,大根堆插入新元素
                        
    					//先弹出 在插入
    					pop_heap(maxheap.begin(), maxheap.end());
    					auto largest = maxheap.back();
    					maxheap.pop_back();
    					maxheapsize--;
    
    					//最小堆插入
    					minheap.push_back(largest);
    					push_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					minheapsize++;
    
    					//最大堆插入
    					maxheap.push_back(num);
    					push_heap(maxheap.begin(), maxheap.end());
    					maxheapsize++;
    
    				}
    				else
    				{
    					//直接插入大根堆
    					maxheap.push_back(num);
    					push_heap(maxheap.begin(), maxheap.end());
    					maxheapsize++;
    				}
    
    			}
    			else  // num > 小根堆的堆顶
    			{
    				//应该插入小根堆 下面就插入小根堆的情况进行讨论
    
    				if (minheapsize + 1 - maxheapsize > 1)
    				{
    					//先弹出 在插入
    					pop_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					auto smallest = minheap.back();
    					minheap.pop_back();
    					minheapsize--;
    
    					//最大堆插入
    					maxheap.push_back(smallest);
    					push_heap(maxheap.begin(), maxheap.end());
    					maxheapsize++;
    
    					//最小堆插入
    					minheap.push_back(num);
    					push_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					minheapsize++;
    				}
    				else
    				{
    					//直接插入小根堆
    					minheap.push_back(num);
    					push_heap(minheap.begin(), minheap.end(), std::greater<>{});
    					minheapsize++;
    				}
    			}
    		}
    	}  //end void addNum(int num) 
    
    	double findMedian()
    	{
    		if (minheapsize == 1 && maxheapsize == 0)
    		{
    			return minheap[0];
    		}
    
    		if ((maxheapsize + minheapsize) % 2 == 0)
    		{
    			return double(maxheap[0] + minheap[0]) / 2;
    		}
    		else  //奇数个
    		{
    			return maxheap[0];
    		}
    	}
    private:
    	vector<int> maxheap;  //大根堆
    	vector<int> minheap;  //小根堆
    	int maxheapsize;
    	int minheapsize;
    
    };
    

    code2对于递增序列,如{1,2,3,4,5}输出的值不正确。
    code1和code2都是有问题的代码,稍后将正确代码上传。

    • 正确的代码

    code1和code2使用递减序列和递增序列就能测出来代码有问题,去网上参考了一下其他人的代码,正确代码如下:

    class MedianFinder
    {
    public:
    	MedianFinder()
    	{
    
    	}
    	void addNum(int num)
    	{
    		if (l_.empty() || num <= l_.top())
    		{
    			l_.push(num);
    		}
    		else
    		{
    			r_.push(num);
    		}
    
    		//step2
    		if (l_.size() < r_.size())
    		{
    			l_.push(r_.top());
    			r_.pop();
    		}
    		else if (l_.size() - r_.size() == 2)
    		{
    			r_.push(l_.top());
    			l_.pop();
    		}
    	}
    	double findMedian()
    	{
    		if (l_.size() > r_.size())
    		{
    			return static_cast<double>(l_.top());
    		}
    		else
    		{
    			return (static_cast<double>( l_.top() + r_.top() )) / 2;
    		}
    	}
    private:
    	priority_queue<int, vector<int>, less<int>> l_;
    	priority_queue<int, vector<int>, greater<int>> r_;
    };
    
  • 相关阅读:
    阅读
    做人做事、原则
    20150913HTML5心得
    动画-七夕言情
    20150818 句子
    网站链接备份
    javascript设计模式2
    javascript设计模式1
    sunlime操作
    node系列4
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/12027821.html
Copyright © 2011-2022 走看看