【每日一题Day72】LC855考场就座 | 构造数据结构 动态数组+二分查找

news2024/9/29 23:24:22

考场就座【LC855】

There is an exam room with n seats in a single row labeled from 0 to n - 1.

When a student enters the room, they must sit in the seat that maximizes the distance to the closest person. If there are multiple such seats, they sit in the seat with the lowest number. If no one is in the room, then the student sits at seat number 0.

Design a class that simulates the mentioned exam room.

Implement the ExamRoom class:

  • ExamRoom(int n) Initializes the object of the exam room with the number of the seats n.
  • int seat() Returns the label of the seat at which the next student will set.
  • void leave(int p) Indicates that the student sitting at seat p will leave the room. It is guaranteed that there will be a student sitting at seat p.

复杂度还可以,至少比官方题解好,希望没分析错

  • 思路:

    2022/12/30

    • 由于每次就座时,有三种情况:
      1. 无人就座:坐在0号座位
      2. 1人就座:坐在0号或者n-1号座位
      3. 2人及以上就座:就座座位与相邻两个座位的最小距离最大,因此可以在已就座的座位中找到相邻两个座位距离一半的最大值 d i s dis dis,并记录前一个座位在序号 p r e S e a t preSeat preSeat,新座位序号即为 p r e S e a t + d i s preSeat+dis preSeat+dis
    • 可以使用哈希表记录每个座位是否有人入座,但是当n很大时,每次在搜索距离的时候,不可避免的会搜索到未就座的座位,时间复杂度为O(n);因此我使用动态数组 i s S e a t e d isSeated isSeated记录已经就座的座位序号,并手动保证数组为升序排列(也可以使用TreeSet 做的时候没想到…),然后遍历数组,按照规律就座以及移除座位序号。
  • 实现

    • 初始化:记录位置数量 n n n

    • seat

      1. 情况1: i s S e a t e d isSeated isSeated大小为0,在0号座位就座

      2. 合并情况2和情况3:

        每次就座时在 p r e S e a t preSeat preSeat的后方插入新座位,因此记录 p r e S e a t preSeat preSeat在数组中的下标 p r e I n d e x preIndex preIndex,在其后方插入新座位,保证数组为升序排列

        • 首先在已就座的座位中找到相邻两个座位距离一半的最大值dis,并记录preIndex
        • 然后处理0号座位未就座的情况,此时的距离为isSeated.get(0),若isSeated.get(0)>dis,那么更新dis以及preIndex
        • 再处理n-1号座位未就座的情况,此时的距离为n- 1 - isSeated.get(size - 1),若n- 1 - isSeated.get(size - 1)>dis,那么更新dis以及preIndex
        • 最后将该位置添加至数组中的相应位置

        (也可以在数组中添加哑结点,就不用额外处理了)

    • leave:二分查找座位p的下标,通过remove删除

    class ExamRoom {
        int n;
        // boolean[] isSeated;
        List<Integer> isSeated;
        public ExamRoom(int n) {
            // isSeated = new boolean[n];
            isSeated = new ArrayList<>();
            this.n = n;
        }
    
        public int seat() {
            int size = isSeated.size();
            if (size == 0){
                isSeated.add(0);
                return 0;
            }
            // else if (size == 1){
            //     int temp = isSeated.get(0);
            //     if (isSeated.get(0) < n / 2){
            //         isSeated.add(1, n - 1);
            //         return n - 1;
            //     }else{
            //         isSeated.add(0, 0);
            //         return 0;
            //     }
            // }
            int dis = 0;
            int preIndex = -1;
            // 首位
            if (isSeated.get(0) != 0 ){
                dis = isSeated.get(0);
            }
            for (int i = 0; i < size - 1; i++){
                int temp = (isSeated.get(i + 1) - isSeated.get(i)) / 2;
                if (dis < temp){
                    dis = temp;
                    preIndex = i;
                }
            }
            // 末尾
            if (n - 1 - isSeated.get(size - 1) > dis){
                dis = n - 1 - isSeated.get(size - 1);
                preIndex = size - 1;
            }
            int ans = preIndex == -1 ? 0 : isSeated.get(preIndex) + dis;
            isSeated.add(preIndex + 1, ans);
            return ans;
        }
    
        public void leave(int p) {
            int l = 0, r = isSeated.size() - 1;
            while (l <= r){
                int mid = (l + r) >> 1;
                if (isSeated.get(mid) == p){
                    isSeated.remove(mid);
                    return;
                }else if (isSeated.get(mid) > p){
                    r = mid - 1;
                }else{
                    l = mid + 1;
                }
            }
        }
    }
    
    • 复杂度

      • 时间复杂度:seat函数的时间复杂度为 O ( P ) O(P) O(P),每次都需要遍历整个动态数组,每次add添加元素的时间复杂度为 O ( P ) O(P) O(P)。leave函数的时间复杂度为 O ( P + l o g P ) O(P+logP) O(P+logP),二分查找的时间复杂度为 O ( l o g P ) O(logP) O(logP),remove时间复杂度为 O ( P ) O(P) O(P)
      • 空间复杂度: O ( P ) O(P) O(P)

      image-20221230162317576

  • TreeSet

    class ExamRoom {
        int N;
        TreeSet<Integer> students;
    
        public ExamRoom(int N) {
            this.N = N;
            students = new TreeSet();
        }
    
        public int seat() {
            //Let's determine student, the position of the next
            //student to sit down.
            int student = 0;
            if (students.size() > 0) {
                //Tenatively, dist is the distance to the closest student,
                //which is achieved by sitting in the position 'student'.
                //We start by considering the left-most seat.
                int dist = students.first();
                Integer prev = null;
                for (Integer s: students) {
                    if (prev != null) {
                        //For each pair of adjacent students in positions (prev, s),
                        //d is the distance to the closest student;
                        //achieved at position prev + d.
                        int d = (s - prev) / 2;
                        if (d > dist) {
                            dist = d;
                            student = prev + d;
                        }
                    }
                    prev = s;
                }
    
                //Considering the right-most seat.
                if (N - 1 - students.last() > dist)
                    student = N - 1;
            }
    
            //Add the student to our sorted TreeSet of positions.
            students.add(student);
            return student;
        }
    
        public void leave(int p) {
            students.remove(p);
        }
    }
    
    作者:力扣 (LeetCode)
    链接:https://leetcode.cn/problems/exam-room/solutions/20105/kao-chang-jiu-zuo-by-leetcode/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 复杂度

      • 时间复杂度:seat函数的时间复杂度为 O ( P + l o g P ) O(P+logP) O(P+logP),每次都需要遍历整个动态数组,每次add添加元素的时间复杂度为 O ( l o g P ) O(logP) O(logP)。leave函数的时间复杂度为 O ( l o g P ) O(logP) O(logP),remove时间复杂度为 O ( l o g P ) O(logP) O(logP)
      • 空间复杂度: O ( P ) O(P) O(P)

      image-20221230162348876

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宝藏又小众的东方行走rpg制作大师素材网站分享

看到大家都在问东方行走rpg制作大师素材&#xff0c;既要免费又要质量好&#xff0c;数量还要多&#xff0c;小编好不容易挖到了宝藏素材网站哦&#xff0c;资源优质数量庞大&#xff0c;使用体验也很好&#xff0c;要是需要的话&#xff0c;赶紧看一看&#xff0c;小编会给大家…

深潜价值互联网蓝海,2022中国区块链产业发展报告发布|陀螺研究院年终献礼...

2022年&#xff0c;是全球发展史上重要的一年&#xff0c;在俄乌冲突以及全球通胀的大背景下&#xff0c;全球经济环境风高浪急、风云诡谲&#xff0c;数字经济正以前所未有的速度冲击着世界固有格局&#xff0c;并成为撬动全球经济复苏和快速增长的新杠杆。围绕数字经济的科技…

软考在哪可以报名?

软考每年有两次考试&#xff0c;分别安排在上半年和下半年&#xff0c;上半年考试时间为5月下旬&#xff0c;下半年考试时间为11月上旬&#xff0c;每年考试时间并不是固定的。 2023年软考考试时间 根据往年软考时间安排来看&#xff0c;预计2023年软考考试时间上半年在5月中…

vue - - - - - 你不知道的技巧

vue - 你不知道的技巧1. 路由参数获取1. 路由参数获取 关于路由参数的获取&#xff0c;相信如下操作很常见: <script> export default {data() {return {};},mounted() {console.log("路由参数", this.$route.params.id);} }; </script>还有一种不太常…

C Primer Plus 第六版(中文版)第十五章(完美修订版)编程练习答案

//本博主所写的代码仅为阅读者提供参考&#xff1b; //若有不足之处请提出&#xff0c;博主会尽其所能修改&#xff1b; //附上课后编程练习题目&#xff1b; //若是对您有用的话请点赞或分享提供给它人&#xff1b; //---------------------------------------------------…

操作系统——进程与线程

进程与线程一、进程的概念1、进程和进程实体2、进程的组织方式3、进程的特征二、进程的状态与转换1、进程的状态2、进程的转换三、进程控制1、定义2、原语控制①创建原语②撤销原语③阻塞原语④唤醒原语⑤切换原语四、进程通信方法一&#xff1a;共享内存方法二&#xff1a;管道…

惠州学院采购JKTD-1000型铁电材料测试仪

惠州学院采购JKTD-1000型铁电材料测试仪 JKTD-1000型铁电材料测试仪 模式测量电路&#xff0c;与传统的 Sawyer-Tawer-模式相比&#xff0c;此电路取消了外接电容&#xff0c;可减小寄生元件的影响。此电路的测试精度取决于积分器积分电容的精度&#xff0c;减少了对测试的影响…

软件测试概念篇

目录 1.软件测试 2.需求 2.1 用户需求 2.2 软件需求 2.3 测试人员眼里的需求 2.4 需求的重要性 3.测试用例 3.1 什么是测试用例 3.2 为什么有测试用例 4.BUG 4.1 BUG的概念 4.2 如何描述一个BUG 4.3 如何定义BUG的优先级 4.4 BUG的生命周期 5.软件生命周期 6. …

RocketMQ 基本概念与工作原理

一、基本概念 消息(Message) 消息&#xff08;Message&#xff09;就是要传输的信息。一条消息必须有一个主题&#xff08;Topic&#xff09;&#xff0c;主题可以看做是你的信件要邮寄的地址。 主题(Topic) Topic表示一类消息的集合&#xff0c;每个主题包含若干条消息&am…

A机器连接同一局域网下的B机器的虚拟机中的mysql

一 背景描述 1.1 需求描述 B机器windows10 的机器ip为&#xff1a; 172.16.71.13 在其上的虚拟机中安装了mysql&#xff0c;虚拟机的ip为 192.168.152.141 。 A机器的ip为&#xff1a;172.16.71.14 &#xff1b; 需求&#xff1a; A机器想访问 B机器172.16.71.13 这台机…

aardio - 【库】libxl库,一个dll操作excel

经常用到excel操作&#xff0c;也有几个现成的库能实现我需要的功能&#xff0c;但用起来总是感觉不顺手。 于是便抽了两天时间&#xff0c;在aaz.libxl库的基础上&#xff0c;按照我的使用习惯进行了修改。 以后再也不用为操作excel发愁啦。 下载地址&#xff1a;http://che…

广州车展|埃安超跑Hyper GT登场,给年少有为者的时代献礼

近年来&#xff0c;随着中国新能源的技术日趋成熟&#xff0c;中国新能源车开始蓬勃发展&#xff0c;逐渐占据了可观的市场份额&#xff0c;并朝着高端化迈进。有一个有趣的现象&#xff1a;希望进军豪华纯电市场的中国车企&#xff0c;几乎都会与特斯拉对标。然而&#xff0c;…

2023新一代设备管理系统助力企业高效化巡检

设备数量和种类都比较多的情况下&#xff0c;工厂设备管理员的工作往往压力巨大&#xff0c;因为生产环环相扣&#xff0c;每一个环节如果出现问题&#xff0c;都会影响到生产。如果隐患不能及时处理&#xff0c;会影响设备的正常和安全运转&#xff0c;严重的会波及到周围相关…

SpringBoot+Shiro+JWT+Mybatis-Plus搭建admin-shiro管理系统

1、项目背景 从零开始搭建一个项目骨架&#xff0c;最好选择合适&#xff0c;熟悉的技术&#xff0c;并且在未来易拓展&#xff0c;适合微服务化体系等。所以一般以Springboot作为我们的框架基础&#xff0c;这是离不开的了。 然后数据层&#xff0c;我们常用的是Mybatis&…

佳创视讯亮相第十八届文博会,VR直播全民化备受瞩目

2022年12月28日,第十八届中国(深圳)国际文化产业博览交易会正式面向公众开放。本届文博会采取线下为主、线上同步的方式,强化线上线下交互联动,旨在推动中华文化产业高质量发展,加强对外文化合作交流。展会共吸引2532家政府组团、文化机构和企业线下参展,870家机构和企业线上参…

SpringSecurity(二十四)--OAuth2:使用JWT和加密签名(下)非对称密钥加密

一、前言 由于上文对称密钥涉及到的内容比较多&#xff0c;所以这一节的非对称密钥加密拆开成这一节单独讲解。 所以大家尽量先阅读完上一章的内容后再浏览这一章内容会更好。 二、使用通过JWT和非对称密钥签名的令牌 本节将实现OAuth2身份验证的一个示例&#xff0c;其中授…

自定义事件实现rpc的调用C++和蓝图实现举例

参考视频&#xff1a;https://www.youtube.com/watch?vGcZQ2o6LpDI 1.自定义事件的方式实现rpc run on server 修改角色的最大速度&#xff0c;方框1&#xff0c;让客户端先行&#xff0c;速度直接改变&#xff1b;然后方框2&#xff0c;告知服务器&#xff0c;自己的速度已经…

双脚在路上,钢笔在手里,想法在脑中,2023年CSDN将在心头

☔️&#xff08;一&#xff09;行走过的道路 一年的时间说长不长&#xff0c;说短不短&#xff0c;所渡过时光的长短在于你是否留意你曾走过的路。 &#x1f434;① 记得2022年初我所许下的flag&#xff0c;是要在CSDN平台上运用今年一年的时间撰写超50篇的技术文章&#xff0…

MySQL-运算符详解

1. 算数运算符 运算符名称作用示例加法计算两个值或表达式的和SELECT A B-减法计算两个值或表达式的差SELECT A - B*乘法计算两个值或表达式的乘积SELECT A * B/或DIV除法计算两个值或表达式的商SELECT A / B%或MOD求模(求余)计算两个值或表达式的余数SELECT A % B 2. 比较运…

vue导入私有组件和注册全局组件和props自定义属性

目录先下载并配置插件导入私有组件注册全局组件props自定义属性使用先下载并配置插件 导入的时候需要路径,有个符号,但不能提示路径,需要手打路径,会发现很麻烦,这时候可以通过vscode插件来解决 vscode搜索Path Autocomplete 配置插件,点击插件设置—扩展设置,点开任意一个set…