IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

数据结构和算法(五)队列及其相关算法

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

队列基础知识

简介

如图(图片来源极客时间的《数据结构与算法之美》专栏

61_1.png

只允许队尾入队,队头出队(即先进先出)的存储结构。

顺序队列

使用数组实现的队列,一般面试常考的队列是循环队列(下面介绍实现)。该队列的特点是:

1、 队列大小固定
2、 出队和入队的时间复杂度为O(1)

链式队列

使用链表的方式实现的队列,该队列的特点为:

1、 队列大小不限
2、 出队和入队的时间复杂度为O(1)

常见算法

实现一个循环队列

循环队列是由双指针 head 、 tail 分别指向队列头和队列尾来实现的。实现循环队列时要注意其队列是否为空和队列是否已经满的判断。条件如下:

队列为空:head == tail

队列已经满:(tail + 1)%capacity == head

代码如下:

class LoopQueue{

          int[] queue = null;
          int capacity = 0;
          int head = 0;
          int tail = 0;

          public LoopQueue(int capacity) {
              this.capacity = capacity;
              queue = new int[capacity];
          }

          public void add(int val){
              if((tail + 1) % capacity == head){
                  System.out.println("队列已满");
              }else {
                  System.out.println("插入值:"+val);
                  tail = tail%capacity;
                  queue[tail] = val;
                  tail++;
              }
          }

          public void remove(){
              if(head%capacity == tail){
                  System.out.println("队列已空");
              }else {
                  head = head%capacity;
                  int val = queue[head];
                  System.out.println("删除的值为:"+val);
                  head++;
              }
          }
      }

设计循环双端队列

设计实现双端队列。
你的实现需要支持以下操作:

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

示例:
MyCircularDeque circularDeque = new MycircularDeque(3); // 设置容量大小为3
circularDeque.insertLast(1);                    // 返回 true
circularDeque.insertLast(2);                    // 返回 true
circularDeque.insertFront(3);                   // 返回 true
circularDeque.insertFront(4);                   // 已经满了,返回 false
circularDeque.getRear();                // 返回 2
circularDeque.isFull();                     // 返回 true
circularDeque.deleteLast();                 // 返回 true
circularDeque.insertFront(4);                   // 返回 true
circularDeque.getFront();               // 返回 4

代码如下:

class MyCircularDeque {

   class Node{
       Node next;
       int value;
       Node(int value){
         this.value = value;
       }
   }

   Node head;
   Node tail;
   int count = 0;
   int capcity;

    /** Initialize your data structure here. Set the size of the deque to be k. */
    public MyCircularDeque(int k) {
       head = new Node(-1);
       tail = new Node(-1);
       capcity = k;
    }

    /** Adds an item at the front of Deque. Return true if the operation is successful. */
    public boolean insertFront(int value) {
        if(count >= capcity)return false;
        Node next = new Node(value);
         if(count == 0){
             head.next = next;
             tail.next = next;
         }else{
             Node p = head.next;
             head.next = next;
             next.next = p;
         }
         count++;
         return true;
    }

    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
    public boolean insertLast(int value) {
       if(count >= capcity)return false;
        Node next = new Node(value);
         if(count == 0){
             head.next = next;
             tail.next = next;
         }else{
             Node p = tail.next;
             tail.next = next;
             p.next = next;
         }
         count++;
         return true;
    }

    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
    public boolean deleteFront() {
       if(count == 0)return false;
       if(count == 1){
         head.next = null;
         tail.next = null; 
       }else{
         Node p = head.next;
         head.next = p.next;
         p.next = null;
       }
       count--;
       return true;
    }

    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
    public boolean deleteLast() {
       if(count == 0)return false;
       if(count == 1){
         head.next = null;
         tail.next = null; 
       }else{
         Node p = tail.next;
         Node root = head.next;
         while(root!=null&&root.next != p)root = root.next;
         tail.next = root;
         root.next = null;
       }
       count--;
       return true;
    }

    /** Get the front item from the deque. */
    public int getFront() {
      if(count == 0)return -1;  
      Node node = head.next;
      return node.value;
    }

    /** Get the last item from the deque. */
    public int getRear() {
      if(count == 0)return -1;  
      Node node = tail.next;
      return node.value;
    }

    /** Checks whether the circular deque is empty or not. */
    public boolean isEmpty() {
       return count == 0;
    }

    /** Checks whether the circular deque is full or not. */
    public boolean isFull() {
      return count == capcity;
    }
}

滑动窗口的最大值

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7] 
解释: 

  滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

实现思路:

将窗口看成一个队列,每次滑动就是一次出队和入队操作。

方法一:如果每次都通过比较来获取队列里的最大值,由于队列大小为 k ,则时间复杂度为 O(n * k).

方法二:当滑动窗口出队的值为队列对头元素时,就让队列中的对头元素出队;当滑动窗口入队的值比队尾元素大时,就让队尾元素出队,不停循环直到队尾元素大于入队元素或者队列为空时,再往队列末尾插入元素。这样就可以让队列里的值满足逆序排序,每次只需要取对头元素即为最大值。

代码如下:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
       if(nums.length == 0)return new int[0]; 
       if(k == 1)return nums;
       int[] res = new int[nums.length - k + 1];
       Deque<Integer> l = new LinkedList<>();
       for(int i = 0;i < k;i++){
           if(l.isEmpty())l.add(nums[i]);
           else{
               while(!l.isEmpty() && nums[i] > l.peekLast()){
                  l.pollLast();
               }
               l.add(nums[i]);
           }
       }
       res[0] = l.peekFirst();
       for(int i = k;i < nums.length;i++){
            if(nums[i - k] == l.peekFirst())l.pollFirst();
            while(!l.isEmpty() && nums[i] > l.peekLast()){
                l.pollLast();
            }
            l.add(nums[i]);
            res[i - k + 1] = l.peekFirst();
       }
       return res;
    }
}

必须掌握的代码实现

  • 用数组实现一个顺序队列
  • 用链表实现一个链式队列
  • 实现一个循环队列

面试常考的与队列相关的算法题

文章永久链接:https://tech.souyunku.com/?p=28158


Warning: A non-numeric value encountered in /data/wangzhan/tech.souyunku.com.wp/wp-content/themes/dux/functions-theme.php on line 1154
赞(95) 打赏



未经允许不得转载:搜云库技术团队 » 数据结构和算法(五)队列及其相关算法

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码
IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

评论 抢沙发

大前端WP主题 更专业 更方便

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏

微信扫一扫打赏


Fatal error: Uncaught Exception: Cache directory not writable. Comet Cache needs this directory please: `/data/wangzhan/tech.souyunku.com.wp/wp-content/cache/comet-cache/cache/https/tech-souyunku-com/index.q`. Set permissions to `755` or higher; `777` might be needed in some cases. in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php:367 Stack trace: #0 [internal function]: WebSharks\CometCache\Classes\AdvancedCache->outputBufferCallbackHandler() #1 /data/wangzhan/tech.souyunku.com.wp/wp-includes/functions.php(5109): ob_end_flush() #2 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(303): wp_ob_end_flush_all() #3 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters() #4 /data/wangzhan/tech.souyunku.com.wp/wp-includes/plugin.php(470): WP_Hook->do_action() #5 /data/wangzhan/tech.souyunku.com.wp/wp-includes/load.php(1097): do_action() #6 [internal function]: shutdown_action_hook() #7 {main} thrown in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php on line 367