LeetCode.1670. 设计前中后队列

题目链接:LeetCode.1670. 设计前中后队列


思路分析:

本题考虑要在中间插入与删除元素,所以不能使用数组实现,故考虑使用链表实现队列,考虑到需要同时在队头与队尾进行操作,所以使用双链表的方法减少时间复杂度。

重点突破

另外有一个要注意的地方是在中间插入与删除时:
1.当插入时,我们利用c++向下取整的特点,可以直接到达需要插入位置的前一个:

void pushMiddle(int val) {
        int mid = len/2;
        LinkedNode* cur = new LinkedNode(val);
        LinkedNode* tem = head;
        while(mid--){
            tem = tem->next;
        }
        cur->next = tem->next;
        cur->pre = tem;
        tem->next = cur;
        cur->next->pre = cur;
        len++;
    }

2.当删除时,链表有效元素个数不同时有不同的操作:
当为双数时:len/2 为 要删除的数;
当为单数时,根据c++向下取整的特点,len/2 为 要删除的数的前一个。

int popMiddle() {
     if(len == 0)
      return -1;
      else{
          int mid = len/2;
          int re;
          LinkedNode* tem = head;
          if(len % 2 == 0)
          {
             while(mid--)
             {
                 tem = tem->next;
             }
             tem->pre->next = tem->next;
             tem->next->pre = tem->pre;
             re = tem->data;
          }
          else{
              while(mid--){
                  tem = tem->next;
              }
              re = tem->next->data;
              tem->next->next->pre = tem;
              tem->next= tem->next->next;
          }
          len--;
          return re;
      }
    }

代码实现:

class FrontMiddleBackQueue {
public:
  struct LinkedNode{
      int data;
      LinkedNode* next;
      LinkedNode* pre;
      LinkedNode(int v):data(v),next(nullptr),pre(nullptr){}
  };
  FrontMiddleBackQueue() {
  len = 0;
  head->next = rear;
  rear->pre = head;
  }
  
  void pushFront(int val) {
      LinkedNode* cur = new LinkedNode(val);
      cur->next = head->next;
      cur->pre = head;
      head->next = cur;
      cur->next->pre = cur;  
      len++;
  }
  
  void pushMiddle(int val) {
      int mid = len/2;
      LinkedNode* cur = new LinkedNode(val);
      LinkedNode* tem = head;
      while(mid--){
          tem = tem->next;
      }
      cur->next = tem->next;
      cur->pre = tem;
      tem->next = cur;
      cur->next->pre = cur;
      len++;
  }
  
  void pushBack(int val) {
     LinkedNode* cur = new LinkedNode(val);
      cur->next = rear;
      cur->pre = rear->pre;
      cur->pre->next = cur;
      rear->pre = cur;
      len++;
  }
  
  int popFront() {
  if(len == 0)
    return -1;
  else{
      LinkedNode* tem = head->next;
      head->next = head->next->next;
      tem->next->pre = head;
      len--;
      return tem->data;
  }
  }
  
  int popMiddle() {
   if(len == 0)
    return -1;
    else{
        int mid = len/2;
        int re;
        LinkedNode* tem = head;
        if(len % 2 == 0)
        {
           while(mid--)
           {
               tem = tem->next;
           }
           tem->pre->next = tem->next;
           tem->next->pre = tem->pre;
           re = tem->data;
        }
        else{
            while(mid--){
                tem = tem->next;
            }
            re = tem->next->data;
            tem->next->next->pre = tem;
            tem->next= tem->next->next;
        }
        len--;
        return re;
    }
  }
  
  int popBack() {
   if(len == 0)
    return -1;
  else{
    LinkedNode* tem = rear->pre;
      rear->pre = rear->pre->pre;
      tem->pre->next = rear;
      len--;
      return tem->data;
  }     
  }
  
private:
 int len;
 LinkedNode* head = new LinkedNode(0);
 LinkedNode* rear = new LinkedNode(0);
};

/**
* Your FrontMiddleBackQueue object will be instantiated and called as such:
* FrontMiddleBackQueue* obj = new FrontMiddleBackQueue();
* obj->pushFront(val);
* obj->pushMiddle(val);
* obj->pushBack(val);
* int param_4 = obj->popFront();
* int param_5 = obj->popMiddle();
* int param_6 = obj->popBack();
*/

你可能感兴趣的:(笔记,链表,数据结构,c++,leetcode)