算法-堆

堆的基础知识:

入堆push,复杂度O(logn)

出堆pop,复杂度O(1)


常见算法应用:

1.数组第k大元素;

2.查找中位数


1.求数组第k大元素

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int,vector<int>,greater<int>> max(nums.begin(),nums.begin()+k);
        //维护一个最小堆,前k个值初始化为数组前k个值
        int len=nums.size();
        for(int i=k;i<len;i++){     //注意从k开始,因为前面的已经入堆
            if(nums[i]>max.top()){  //若大于对顶则pop出堆顶,将当前数组元素入堆
                max.pop();
                max.push(nums[i]);
            }
        }
        return max.top();  //直接去堆顶即为第k大元素
    }
};

用快排时间复杂度O(nlogn),这里用堆。由于堆规模最大为k,故每次push复杂度O(logk),n次为O(nlogk),优于快排。


2.中位数

class MedianFinder {
public:
    /** initialize your data structure here. */
    MedianFinder() {
         
    }
    
    void addNum(int num) {
        if(max.empty()){
            max.push(num);
            return;
        }
        if(max.size()<=min.size()){
            if(num<=min.top()){
                max.push(num);
            }else{
                max.push(min.top());
                min.pop();
                min.push(num);
            }
        }else{
            if(num<=max.top()){
                min.push(max.top());
                max.pop();
                max.push(num);
            }else{
                min.push(num);
            }
        }
    }
    
    double findMedian() {
        if(max.empty() && min.empty()) return 0;
        else if(max.size()==min.size()) return (double)(max.top()+min.top())/2;//注意转化为double
        else return max.size()>min.size()?max.top():min.top();
    }
private:
    priority_queue<int> max;
    priority_queue<int,vector<int>,std::greater<int> > min;
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */
原文地址:https://www.cnblogs.com/chendaniu/p/10274561.html