队列

队列queue

c++

  • 定义
queue<int> queue;
  • 入队
queue.push(num);
  • 出队
queue.pop();
//队列为空时出队报错
if(!queue.empty()) queue.pop();
  • 获取队列大小、队首、队尾元素方法
queue.size()
queue.front()
queue.back()
  • 清空队列
while(!queue.empty()){
      queue.pop();
}

python

python中的队列直接用List实现 内核即:

queue = []

但更常用双端队列,见下面内容。

双端队列deque

双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。

 

 

 

c++

  • 定义
deque<int> deque;
  • 入队
// 从队首入队 
deque.push_front(num);

// 从队尾入队
deque.push_back(num);

/*没有了que.push()方法*/
  • 出队
// 从队首出队 
deque.pop_front(num);

// 从队尾出队
deque.pop_back(num);

/*没有了que.pop()方法*/
  • 获取队列大小、队首、队尾元素方法
deeue.size()
deeue.front()
deeue.back()
  • 清空队列
while(!deque.empty()){
      deque.pop_back();
      //deque.pop_front();
} 

 

python

python中的双端队列在内置模块collections中,是python标准库;collections包含了一些特殊的容器,针对Python内置的容器,例如list、dict、set和tuple,提供了另一种选择。

这里只说deque,其他的还有例如

  1. 计数器(Counter)
  2. 默认字典(defaultdict)
  3. 有序字典(OrderedDict)
  4. 可命名元组(namedtuple)
  • 定义
deque = collections.deque()
  • 入队
# 从队尾入队
deque.append(num)

# 从队尾入队
deque.appendleft(num)
  • 出队
# 从队尾出队
deque.pop()

# 从队尾出队
deque.popleft()
  • 获取队列大小、队首、队尾元素方法
len(deque)
# 同时还可以对队列中某个元素出现个数进行统计
deque.count(num)

# 返回对首元素
deque[0]

# 返回队尾元素
deque[-1]
  • 清空队列
deque.clear()

 example_1:序列上滑动窗口中的最大值

题目来源:剑指 Offer 59 - I. 滑动窗口的最大值 - 力扣(LeetCode) (leetcode-cn.com)

    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        //滑动窗口  + 维护一个单调的队列
        deque<int> monoQueue; //c++中也有deque  常用这个才对
        vector<int> res;
        int n = nums.size();
        for(int i = -k+1;i<n-k+1;i++){
            int j = i+k-1;
            // 如果出窗口的刚好是上一轮的最大值
            if(i>0 && nums[i-1] == monoQueue.front()){
                monoQueue.pop_front();
            }
            //保证单调的队列
            while(!monoQueue.empty() && monoQueue.back() <nums[j]){
                monoQueue.pop_back();
            }

            monoQueue.push_back(nums[j]);
            if(i>=0){
                res.push_back(monoQueue.front());
            }
        }
        return res;

    }
c++
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
    # 使用双端队列(单调队列)
    res= []
    monoQueue = collections.deque()
    n = len(nums)
    for i,j in zip(range(-k+1,n-k+1),range(n)): # 滑动窗口还可以这样???? 学习了
        if i > 0 and monoQueue[0] == nums[i-1]: # 如果最大值刚好是刚被弹出的那个元素,那么要把队列首pop出去 
            monoQueue.popleft()
        # 保证monoQueue递减
        while monoQueue and monoQueue[-1] < nums[j]:
            monoQueue.pop()
        
        monoQueue.append(nums[j])

        if i>=0:
            res.append(monoQueue[0])
    return res
python

 example_2:自定义MaxQueue

class MaxQueue:
"""  菜鸡做法  维护一个单调队列
# 首先如果只维护一个最大值,但是当最大值出队后,不能用O(1)的时间来找下一个max value
# 利用 数据结构 来实现,即经常使用的 “空间换时间” 。

    def __init__(self):
        self.queue = []
        self.monoque = collections.deque()

    def max_value(self) -> int:
        if self.monoque:
            return self.monoque[0]
        else:
            return -1


    def push_back(self, value: int) -> None:
        self.queue.append(value)
        while self.monoque and self.monoque[-1]<value:
            self.monoque.pop()
        self.monoque.append(value)


    def pop_front(self) -> int:
        
        if self.queue:
            if self.queue[0]==self.monoque[0]:
                self.monoque.popleft()
            ret = self.queue[0]
            self.queue = self.queue[1:]
            return ret
        else:
            return -1


"""
python
class MaxQueue {
    queue<int> que;
    deque<int> deq;
public:
    MaxQueue() { }
    int max_value() {
        return deq.empty() ? -1 : deq.front();
    }
    void push_back(int value) {
        que.push(value);
        while(!deq.empty() && deq.back() < value)
            deq.pop_back();
        deq.push_back(value);
    }
    int pop_front() {
        if(que.empty()) return -1;
        int val = que.front();
        if(val == deq.front())
            deq.pop_front();
        que.pop();
        return val;
    }
};
c++

 

posted @ 2021-10-26 21:56  PiaYie  阅读(279)  评论(0编辑  收藏  举报