【数据结构和算法】_03_优先队列 & 双向队列


 

【一】 Priority Queue(优先队列)- 正常入,按优先级出

 

  • 实现机制1Heap(Binary,Binomial,Fibonacci)

 

  • 实现机制2Binary Search Tree(二叉搜索树)

 
 

【二】 Mini Heap(小顶堆)- 父亲节点 < 左右孩子节点

 
 

【三】 Max Heap(大顶堆)- 父亲节点 > 左右孩子节点

 
 

【四】 Interview(面试题)

 

【4.1】 LeetCode 703:Kth Largest Element in a Stream(数据流中的第K大元素)

 

// c++( priority_queue,优先队列 )
class KthLargest {

public:
    KthLargest(int k, vector<int>& nums) {
    	// 遍历 nums
        for(int num : nums){
            q.push(num);
            if(q.size() > k) q.pop();
        }
        K = k;
    }
    
    int add(int val) {
        q.push(val);
        if(q.size() > K) q.pop();
        return q.top();
    }
    
private:
    // c++优先队列容器,实现了最小堆,每次进行操作均会自动排序
    priority_queue<int, vector<int>, greater<int>> q;
    int K; // 用于 add 操作中传值判断
    
};

 

【4.2】 LeetCode 239:Sliding Window Maximum(滑动窗口最大值)

 

# python(直接用数组实现双向队列)
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        # 如果传进来的 nums 为空,则返回空 list
        if not nums: return []
        window, res = [], []
        # i 是索引,即元素下标,x 是元素本身
        for i, x in enumerate(nums):
            # 窗口大小为k,判断是否需要将队列前排元素弹出
            if window and window[0] <= i-k: 
                window.pop(0)
            # 弹出 比准备进来的元素小的 数的下标
            while window and nums[window[-1]] <= x:
                window.pop()
            # 将元素下标加入数组
            window.append(i)
            # 存储 nums[队列最前面的下标]
            if i >= k-1:
                res.append(nums[window[0]])
        return res
// c++( deque,双向队列 )
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        // if(nums.empty()) return 0; 无法执行该语句
        vector<int> res; // 数组容器
        deque<int> window; // 双向队列容器,存储数组元素的下标
        // 遍历数组
        for(int i = 0; i < nums.size(); i++) {
            // 当 双向队列的第一个值(下标) == i-k 时,出队列,维持大小为 k 的窗口
            if(!window.empty() && window.front() == i-k) window.pop_front();
            // 当 新传进来的值 >= nums[队列末尾的值],出队列
            while(!window.empty() && nums[window.back()] <= nums[i]) window.pop_back();
            // 将元素下标压进队列
            window.push_back(i);
            // 最大的元素的下标,始终在队列的最前面,存进数组里
            if(i >= k-1) res.push_back(nums[window.front()]);
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值