力扣每日一题(难的我也不会)641. 设计循环双端队列(2022.8.15)

641. 设计循环双端队列

设计实现双端队列。

实现 MyCircularDeque 类:

  • MyCircularDeque(int k) :构造函数,双端队列最大为 k 。
  • boolean insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true ,否则返回 false 。
  • boolean insertLast() :将一个元素添加到双端队列尾部。如果操作成功返回 true ,否则返回 false 。
  • boolean deleteFront() :从双端队列头部删除一个元素。 如果操作成功返回 true ,否则返回 false 。
  • boolean deleteLast() :从双端队列尾部删除一个元素。如果操作成功返回 true ,否则返回 false 。
  • int getFront() ):从双端队列头部获得一个元素。如果双端队列为空,返回 -1 。
  • int getRear() :获得双端队列的最后一个元素。 如果双端队列为空,返回 -1 。
  • boolean isEmpty() :若双端队列为空,则返回 true ,否则返回 false  。
  • boolean isFull() :若双端队列满了,则返回 true ,否则返回 false 。

        在之前的设计哈希表,设计链表,设计循环队列中我们都提到过对于链表的Node节点应该怎样设计,在此我就不赘述了,需要的可以查看之前的链接

(2条消息) 力扣每日一题(难的我也不会)622. 设计循环队列(2022.8.2)_晓晓的小小的博客-CSDN博客(2条消息) 力扣706. 手写简单hash表(2022.7.30)_晓晓的小小的博客-CSDN博客_手写哈希表(2条消息) 力扣707. 设计链表(2022.8.5)_晓晓的小小的博客-CSDN博客

我们设计的Node节点如下

    class Node {
        Node prev;
        Node next;
        int val;

        public Node() {
        }

        public Node(int val) {
            this.val = val;
        }
    }

        对于链表这种题型我们首先根据题意判断是否需要虚拟头节点,显然这道题需要虚拟头结点,而且还需要虚拟尾结点,之后我们还需要一个整数size表示当前队列长度,以及k表示队列总长度

我们设计的属性如下

    Node head;
    Node tail;
    int size;
    int k;

        对于这道题我们主要实现四个方法

boolean insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true ,否则返回 false 
boolean insertLast() :将一个元素添加到双端队列尾部。如果操作成功返回 true ,否则返回 false 
boolean deleteFront() :从双端队列头部删除一个元素。 如果操作成功返回 true ,否则返回 false 
boolean deleteLast() :从双端队列尾部删除一个元素。如果操作成功返回 true ,否则返回 false

        对于头部插入操作,我们需要找到虚拟头结点,之后新建一个数据节点,让虚拟头结点指向数据节点,并让数据节点的prev指针指向虚拟头结点,让数据节点的next指针指向之前虚拟头结点的下一个节点

代码如下

    public boolean insertFront(int value) {
        if (size >= k) return false;
        Node next = head.next;
        Node node = new Node(value);
        head.next = node;
        node.prev = head;
        next.prev = node;
        node.next = next;
        size++;
        return true;
    }

        插入尾节点同理,待会看代码就能懂

        对于删除头结点操作,我们首先记录下头结点的下一个的下一个节点(需要先判空),之后直接让头结点的next指针指向记录的节点,让记录的节点指向头结点,在Java中如果没有强引用指向一个对象,那么jvm会回收掉这个对象,所以我们并不用关心节点的回收,交给垃圾回收器即可

代码如下

    public boolean deleteFront() {
        if (size == 0) return false;
        Node next = head.next.next;
        head.next = next;
        next.prev = head;
        size--;
        return true;
    }

        删除尾节点同理

整体代码如下

class MyCircularDeque {

    class Node {
        Node prev;
        Node next;
        int val;

        public Node() {
        }

        public Node(int val) {
            this.val = val;
        }
    }

    Node head;
    Node tail;
    int size;
    int k;

    public MyCircularDeque(int k) {
        this.k = k;
        size = 0;
        head = new Node();
        tail = new Node();
        head.next = tail;
        tail.prev = head;
    }

    public boolean insertFront(int value) {
        if (size >= k) return false;
        Node next = head.next;
        Node node = new Node(value);
        head.next = node;
        node.prev = head;
        next.prev = node;
        node.next = next;
        size++;
        return true;
    }

    public boolean insertLast(int value) {
        if (size >= k) return false;
        Node node = new Node(value);
        Node prev = tail.prev;
        prev.next = node;
        node.prev = prev;
        tail.prev = node;
        node.next = tail;
        size++;
        return true;
    }

    public boolean deleteFront() {
        if (size == 0) return false;
        Node next = head.next.next;
        head.next = next;
        next.prev = head;
        size--;
        return true;
    }

    public boolean deleteLast() {
        if (size == 0) return false;
        Node prev = tail.prev.prev;
        prev.next = tail;
        tail.prev = prev;
        size--;
        return true;
    }

    public int getFront() {
        return size == 0 ? -1 : head.next.val;
    }

    public int getRear() {
        return size == 0 ? -1 : tail.prev.val;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean isFull() {
        return size == k;
    }
}

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque obj = new MyCircularDeque(k);
 * boolean param_1 = obj.insertFront(value);
 * boolean param_2 = obj.insertLast(value);
 * boolean param_3 = obj.deleteFront();
 * boolean param_4 = obj.deleteLast();
 * int param_5 = obj.getFront();
 * int param_6 = obj.getRear();
 * boolean param_7 = obj.isEmpty();
 * boolean param_8 = obj.isFull();
 */

你可能感兴趣的:(leetcode,链表,算法)