高频算法面试题 3.队列(Queue)

  • 定义:
    特殊的线性表,只能在前端删除,后端插入,先进先出(FIFO—first in first out)线性表。类比排队一样,先排进队列的人先出去。
  • 代码实现:
#FIFO: first item we insert will be the first we take out
class Queue:

    #we represent the queue with the help of an array
    def __init__(self):
        self.queue = []
        
    #checks if the queue is empty or not    
    def is_empty(self):
        return self.queue == []
        
    #inserting items 
    def enqueue(self, data):
        self.queue.append(data)
        
    #getting items
    def dequeue(self):
    
        #maybe there is no item in the queue
        if self.is_empty():
            raise Exception("Queue is empty...")
    
        #getting the first item
        data = self.queue[0]
        del self.queue[0]
        return data
        
    #getting the item without removing it
    def peek(self):
        
        #maybe there is no item in the queue
        if self.is_empty():
            raise Exception("Queue is empty...")
    
        return self.queue[0]
    
    #size of the queue
    def size_queue(self):
        return len(self.queue)
    
if __name__ == "__main__":      
    
    queue = Queue()
    
    queue.enqueue(10)
    queue.enqueue(20)
    queue.enqueue(30)
    
    print(queue.size_queue())
    print("Dequeue: ", queue.dequeue())
    print("Dequeue: ", queue.dequeue())
    print(queue.size_queue())


题目

225和239


leetcode 239

思路
暴力解法: 遍历所有区间,[0,len(nums)-k)], 遍历[x,x+k]窗口得到最大值.
为什么优化解法用到max-heap(堆)呢? 因为窗口每次向右滑动都是减去一个值 加上一个最大值,符合堆的特性.


暴力和O(nlogn)解法

https://realpython.com/modern-web-automation-with-python-and-selenium/

O(n)解法
观察数组中数的性质:
如果窗口中有a,b两数,a在b之前,且a <= b, 那么a不可能为最大值。
如图,注意到窗口中的数是单调递减的


原来的数组
image
按照性质去掉符合的数之后

算法


O(n)解法

实现
*双端队列:双端队列是指允许两端都可以进行入队和出队操作的队列


image.png
class Solution(object):
    
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        from collections import deque
        #定义插入一个数的操作,输入是(时间戳,数字)
        def add(i,num):
            #判断队首是否应该出队
            if len(q) != 0 and q[0][0] == i-k:
                q.popleft()
            #判断队尾是否应该出队
            while (len(q) != 0 and num >= q[-1][1]):
                q.pop()
            #插入新二元组
            q.append((i,num))
            
            #返回队首,即当前最大值
            return q[0][1]
        q = deque()
        
        res = []
        for i,num in enumerate(nums):
            res.append(add(i,num))
        
        #结果只保留k-1往后的,前面的结果都不到k个数
        return res[k-1:]

leetcode相关

  1. #225 Implement Stack using Queues
  2. #232 Implement Queue using Stacks
  3. #239 Sliding Window Maximum
  4. #621 Task Scheduler
  5. #622 Design Circular Queue
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,783评论 1 32
  • 1.设计模式是什么? 你知道哪些设计模式,并简要叙述?设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型...
    龍飝阅读 2,321评论 0 12
  • 很容易满足 一粥两饭三餐四季 空气里都弥漫着知足常乐的味道 对于一个吃货来说 你多么英俊潇洒 英明神武 都比不过一...
    未晓啊阅读 335评论 0 3
  • 敬畏一切,回归简单 这一场胃病折磨我了这快一个十一长假,从最初...
    拙兰阅读 460评论 11 14

友情链接更多精彩内容