295.Find Median from Data Stream

Title description

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

For example, [2,3,4], the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

  • void addNum(int num) - Add a integer number from the data stream to the data structure.

  • double findMedian() - Return the median of all elements so far.

Example

addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2

Follow up

1.If all integer numbers from the stream are between 0 and 100, how would you optimize it?

2.If 99% of all integer numbers from the stream are between 0 and 100, how would you optimize it?

degree of difficulty

Hard

Solution 1: Create an array and use binary search

class MedianFinder {
 public : 
    MedianFinder () { 
    
    } 
    // Adds a number into the data structure. 
    void addNum ( int num) {
         int left = 0 , right = nums.size () -1 ;
          // Note that the condition of the loop is less than Equal to, when = condition, still need to judge whether to insert 
        while (left <= right) 
        { 
            int mid = (left + right) / 2 ;
             if (nums [mid] <num) left = mid + 1 ;
             else right = mid- 1 ;  
        }
        nums.insert (nums.begin ()+left, num);
    }
 
    // Returns the median of current data stream
    double findMedian() {
        int n = nums.size();
        if(n%2==1) return nums[n/2];
        return (nums[n/2-1] + nums[n/2])/2.0;
    }
private:
    vector<int> nums;
};

 

 

Solution 2: Use a large top heap and a small top heap respectively to divide the array into two halves.

class MedianFinder {
 private :
     / * 
     * Create a large top heap and a small top heap, the large top heap holds the left half of the data, and the small top heap holds the right part * / 
    // The small top heap 
    priority_queue < int , vector < int >, greater < int >> small;
     // The default large top heap 
    priority_queue < int > large;
     void balance_heaps () {
         if (small.size ()> large.size () + 1 ) {
             int moved = small.top (); 
            small.pop (); 
            large.push (moved); 
        } else  if (large.size() > small.size() + 1) {
            int moved = large.top();
            large.pop();
            small.push(moved);
        }
    }
public:
    /** initialize your data structure here. */
    MedianFinder() {
        small.push(numeric_limits<int>::max()); // dummy values for corner case
        large.push(numeric_limits<int>::min());
    }
​
    void addNum(int num) {
        if (num > small.top()) {
            small.push(num);
        } else {
            large.push(num);
        }
        balance_heaps();
    }
​
    double findMedian() {
        if (small.size() == 1 && large.size() == 1)
            return 0; // No numbers
        if (small.size() == large.size()) {//偶数的情况
            return (small.top() + large.top()) / 2.0;
        } else if (small.size() > large.size()) {//奇数的情况
            return small.top();
        } else {
            return large.top();
        }
    }
​
};
 
/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder* obj = new MedianFinder();
 * obj->addNum(num);
 * double param_2 = obj->findMedian();
 */

 

 

Guess you like

Origin www.cnblogs.com/AntonioSu/p/12735120.html