首页 > 其他分享 >力扣(leetcode)每日一题 1845 座位预约管理系统| treeSet和priority Queue的区别|线段树

力扣(leetcode)每日一题 1845 座位预约管理系统| treeSet和priority Queue的区别|线段树

时间:2024-10-01 10:22:54浏览次数:10  
标签:node Queue right int res 1845 priority public left

之前发过一篇,感觉还有深挖的地方,于是又补充一些信息
这题目虽然是middle难度题目,要解答出来是只要easy的时间,但是深挖可以有hard的难度

题解1 可以帮助复习线段树的使用,题解2 可以复习一下java基础知识

题解1 线段树

这是自己憋出来的线段树
在这里插入图片描述

  class SeatManager {
        public SeatManager(int n) {  // 假设座位都是0 如果坐了人就设置为1 如果返回座位就减去1  需要找到靠左边的最小值。
            int length = n + 1;
            right = n;
            arr = new int[length];
            minArr = new int[length * 4];
        }

        int[] arr;
        int[] minArr;
        int left = 1;
        int right;
        int root = 1;

        public int reserve() {
            int res = getMin();
            update(res, 1);
            return res;
        }

        public void unreserve(int seatNumber) {
            update(seatNumber, -1);
        }

        public int getMin() {
            return getMin(left, right, root);
        }

        public int getMin(int left, int right, int node) {
            if (left == right) {
                return left;
            }
            int mid = (left + right) / 2;
            int res;
            if (minArr[node * 2] == 0) {  // 只要左边的最小值还是0,那么需要的点必然还在左边
                res = getMin(left, mid, node * 2);
            } else {
                res = getMin(mid + 1, right, node * 2 + 1);
            }
            return res;
        }

        public void update(int index, int value) {
            update(index, value, left, right, root);
        }

        public void update(int index, int value, int left, int right, int node) {
            if (left == right) {
                // 更新值
                arr[left] += value;
                minArr[node] = arr[left];
                return;
            }
            // 这里需要对arr进行更新操作
            int mid = (left + right) / 2;
            if (index <= mid) {
                update(index, value, left, mid, node * 2);
            }
            if (index > mid) {
                update(index, value, mid + 1, right, node * 2 + 1);
            }
            minArr[node] = Math.min(minArr[node * 2], minArr[node * 2 + 1]);
        }
    }

这里是抄别人思路憋出来的线段树
在这里插入图片描述


 class SeatManager {
        public SeatManager(int n) {
            int length = n + 1;
            right = n;
            hasSeatArr = new int[length * 4]; // 先假设1,都是有座位的
            Arrays.fill(hasSeatArr, 1);
        }

        int[] hasSeatArr;
        int left = 1;
        int right;
        int root = 1;

        public int reserve() {
            int res = getMin();
            update(res, 0);
            return res;
        }

        public void unreserve(int seatNumber) {
            update(seatNumber, 1);
        }

        public int getMin() {
            return getMin(left, right, root);
        }

        public int getMin(int left, int right, int node) {
            if (left == right) {
                return left;
            }
            int mid = (left + right) / 2;
            int res;
            if (hasSeatArr[node * 2] > 0) {  // 只要左边有座位,就往左边移动
                res = getMin(left, mid, node * 2);
            } else {
                res = getMin(mid + 1, right, node * 2 + 1);
            }
            return res;
        }

        public void update(int index, int value) {
            update(index, value, left, right, root);
        }

        public void update(int index, int value, int left, int right, int node) {
            if (left == right) {
                hasSeatArr[node] = value;
                return;
            }
            // 这里需要对arr进行更新操作
            int mid = (left + right) / 2;
            if (index <= mid) {
                update(index, value, left, mid, node * 2);
            }
            if (index > mid) {
                update(index, value, mid + 1, right, node * 2 + 1);
            }
            hasSeatArr[node] = Math.max(hasSeatArr[node * 2], hasSeatArr[node * 2 + 1]); // 只要有一个有位置就可以了
        }
    }


作者写题解的时候说是接近双百,但是我抄他的跑了一下,和赋值他的跑了一下,排名都不高。可能当年写题解写的比较早

题解2


TreeSet是红黑树
PriorityQueue是完全二叉树
前者的 iterator是有序的,后者是不保证有序的

这里就是简单的将treeSet改成了PriorityQueue

    class SeatManager {
        // 将初始化的时间给优化了,min用1开始发放,不断累加。如果有回收的作为用treeSet收集。如果treeSet不为空,优先从treeSet弹出安排座位
//        TreeSet<Integer> treeSet = new TreeSet<>();
        private final PriorityQueue<Integer> queue = new PriorityQueue<>();

        int min = 1;

        public SeatManager(int n) {
        }

        public int reserve() {
            if (queue.isEmpty()) {
                int res = min;
                min++;
                return res;
            } else {
                return queue.poll();
            }
        }

        public void unreserve(int seatNumber) {
            queue.add(seatNumber);
        }
    }

在这里插入图片描述

标签:node,Queue,right,int,res,1845,priority,public,left
From: https://blog.csdn.net/ganjiee0007/article/details/142665900

相关文章

  • message_queue
    学习过程中,我发现了一扇新的世界,Thecstandardmanual这里记录文件skynet_mq.handskynet_mq.c的阅读结果.消息队列1.为什么用队列?因为消息需要先入先出(FIFO).剩下几个问题:如何自己在代码中也使用自旋锁,请写一个示例代码。次级消息队列(messagequeue)中的字段......
  • 1845. 座位预约管理系统
    请你设计一个管理n个座位预约的系统,座位编号从1到n。请你实现SeatManager类:SeatManager(intn)初始化一个SeatManager对象,它管理从1到n编号的n个座位。所有座位初始都是可预约的。intreserve()返回可以预约座位的最小编号,此座位变为不可预约。voidunres......
  • C++学习:stack queue模拟
    stack和queue可以复用其他容器的函数如dequevector这两个是空间适配器,所以都没有迭代器一:stack模拟namespacebit{ template<classT,classContainer=deque<T>> classstack { public: voidpush(constT&x) { _con.push_back(x); } voidpop() ......
  • [Java基础]PriorityQueue
    优先级队列数据结构是堆一.PriorityQueuePriorityQueue简介继承关系PriorityQueue示例二.Comparable比较器Compare接口三.Comparator比较器Comparator接口四.底层原理一.PriorityQueuePriorityQueue简介PriorityQueue,即优先级队列。优先级队列可以保证......
  • 【JUC并发编程系列】深入理解Java并发机制:阻塞队列详解与简单纯手写(七、BlockingQueu
    文章目录【JUC并发编程系列】深入理解Java并发机制:阻塞队列详解与简单纯手写(七、BlockingQueue、ArrayBlockingQueue、LinkedBlocking)1.简单回顾1.1数组结构和链表结构1.1.1数组结构1.1.2链表结构1.2有界队列与无界队列1.3Lock锁使用回顾2.什么是阻塞队列3.B......
  • RabbitMQ通讯方式第二讲:Work Queues
    了解WorkQueues  1.1官网中的图片:通过官网里的图片,我们可以看到WordQueues与HelloWorld的区别,这里的消费者增加,但是时多个消费者消费单个队列,在这里我们依然要注意,这里面使用的是默认的交换机,并不是直接连接的队列。  1.2直观的图片:更好的理解每次的连接都是......
  • ConcurrentLinkedQueue详解(图文并茂)
    前言ConcurrentLinkedQueue是基于链接节点的无界线程安全队列。此队列按照FIFO(先进先出)原则对元素进行排序。队列的头部是队列中存在时间最长的元素,而队列的尾部则是最近添加的元素。新的元素总是被插入到队列的尾部,而队列的获取操作(例如poll或peek)则是从队列头部开始。与传统的L......
  • ConcurrentLinkedQueue详解(图文并茂)
    前言ConcurrentLinkedQueue是基于链接节点的无界线程安全队列。此队列按照FIFO(先进先出)原则对元素进行排序。队列的头部是队列中存在时间最长的元素,而队列的尾部则是最近添加的元素。新的元素总是被插入到队列的尾部,而队列的获取操作(例如poll或peek)则是从队列头部开始。与传统的......
  • stack - queue
    1.容器适配器(1)什么是适配器?适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口(2) STL标准库中stack和queue的底层结构 虽然stack和queue中也可以存......
  • priority_queue的模拟实现
    priority_queue的模拟实现1.priority_queue的介绍和使用1.1priority_queue的介绍1.2priority_queue的使用2.priority_queue的模拟实现3.堆排序1.priority_queue的介绍和使用1.1priority_queue的介绍优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个......