【LeetCode】641. 设计循环双端队列

168 阅读2分钟

image.png

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    image.png

  • 题目解析

    • 1 <= k <= 1000
    • 0 <= value <= 1000
    • insertFront, insertLast, deleteFront, deleteLast, getFront, getRear, isEmpty, isFull  调用次数不大于 2000 次

二、思路分析:

我们本题读取题目,题目要求设计双端的队列对象MyCircularDeque,双端队列可以头尾都可以添加删除元素,那么MyCircularDeque对象有哪些方法呢:

  • MyCircularDeque 对象__init__()函数创建创建长度为k队列self.deque
  • insertFront()在circularDeque列表中头部添加元素,当self.deque长度超过k时则返回False,反之True
  • insertLast()在circularDeque列表中尾部添加元素,当self.deque长度超过k时则返回False,反之True
  • deleteFront()在circularDeque列表中头部删除元素,当self.deque长度为0时则返回False,反之True
  • deleteLast()在circularDeque列表中尾部删除元素,当self.deque长度为0时则返回True,反之True
  • getRear()获取self.deque尾部元素
  • getFront()获取self.deque头部元素
  • isFull()判断self.deque长度是否等于k
  • isEmpty()判断self.deque长度为零

我们看到MyCircularDeque的方法,我们直接可以使用数组的方式进行模拟双端队列,作为初学者来说,脑袋立马想到了Python中列表相关的方法:

  • list.insert(0,value),可以在insertFrot()方法中调用将value添加头部
  • list.append(value),可以在insertLast()方法中调用将value添加尾部
  • list.pop(0),可以在deleteFront()方法中调用将头部元素推出掉
  • list.pop(),可以在deleteLast()方法中调用将尾部元素推出掉
  • isFull()中,len(self.deque) == self.k
  • isEmpty()中,len(self.deque) == 0
    class MyCircularDeque(object):
    
        def __init__(self, k):
            """
            :type k: int
            """
            self.k = k
            self.deque = []
            self.idex = 0
    
        def insertFront(self, value):
            """
            :type value: int
            :rtype: bool
            """
            if self.idex < self.k:
                self.idex +=1 
                self.deque.insert(0,value)
                return True
            else:
                return False
    
        def insertLast(self, value):
            """
            :type value: int
            :rtype: bool
            """
            if self.idex < self.k:
                self.idex +=1
                self.deque.append(value)
                return True
            else:
                return False
    
        def deleteFront(self):
            """
            :rtype: bool
            """
            if self.idex !=0:
                self.idex -=1
                self.deque.pop(0)
                return True
            else:
                return False
    
        def deleteLast(self):
            """
            :rtype: bool
            """
            if self.idex != 0:
                self.idex -=1
                self.deque.pop()
                return True
            else:
                return False
    
        def getFront(self):
            """
            :rtype: int
            """
            return self.deque[0] if self.idex !=0 else -1
    
    
        def getRear(self):
            """
            :rtype: int
            """
            return self.deque[len(self.deque)-1] if self.idex !=0 else -1
    
        def isEmpty(self):
            """
            :rtype: bool
            """
            return False if len(self.deque) > 0  else True
    
    
        def isFull(self):
            """
            :rtype: bool
            """
            return False if len(self.deque) < self.k else True
    

以上实现是纯菜鸟小白写的代码,严格意义上并不是从原理来实现双端队列,那么真正去实现这个双端队列,我们可以使用数组+双指针来模拟:

  • MyCircularDeque 初始化中定义两个指针left和right, left赋值为0,right赋值为-1
  • left指针从右往左移动,right指针从左往右移动
  • insetFront()方法中,left向左移动则-1,self.deque[left]=value
  • insertLast()方法中,right向右移动则+1,self.deque[right]=value
  • deletFront()方法中, left向右移动则+1
  • deletLast()方法中,right向左移动则-1
    class MyCircularDeque(object):
    
        def __init__(self, k):
            """
            :type k: int
            """
            self.k = k
            self.deque = [0]*self.k
            self.left = 0
            self.right = -1
    
        def insertFront(self, value):
            """
            :type value: int
            :rtype: bool
            """
            if self.isFull():
                return False
            self.left -=1
            self.deque[self.left] = value
            return True
    
        def insertLast(self, value):
            """
            :type value: int
            :rtype: bool
            """
            if self.isFull():
                return False
            self.right +=1
            self.deque[self.right] = value
            return True
    
        def deleteFront(self):
            """
            :rtype: bool
            """
            if self.isEmpty():
                return False
            self.left +=1
            return True
    
        def deleteLast(self):
            """
            :rtype: bool
            """
            if self.isEmpty():
                return False
            self.right -=1
            return True
    
        def getFront(self):
            """
            :rtype: int
            """
            return self.deque[self.left] if not self.isEmpty() else -1
    
    
        def getRear(self):
            """
            :rtype: int
            """
            return self.deque[self.right] if not self.isEmpty() else -1
    
        def isEmpty(self):
            """
            :rtype: bool
            """
            return self.left - self.right == 1
    
    
        def isFull(self):
            """
            :rtype: bool
            """
            return self.right - self.left + 1 == self.k
    
    

三、总结:

本题考察双端队列插入元素原理的实现,最简单的方法可以直接调用list内置函数,但是我们也可以使用数组双指针来实现增减元素的过程,如果是高手的话可以使用链表的数据结构来实现整个过程。AC提交记录如下:

image.png

  • 时间复杂度:O(k),k长度
  • 空间复杂度:O(1),没有使用额外空间

以上是本期内容,欢迎大佬们点赞评论,下期见~~