Leetcode 855. Exam Room 考场就座: 提供两种解法

  • 855. Exam Room 考场就座(两种解法)
    • 题目描述
    • 示例:
    • 解答1
    • 代码1
    • 解答2
    • 代码2

855. Exam Room 考场就座(两种解法)

题目描述

In an exam room, there are N seats in a single row, numbered 0, 1, 2, …, 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. (Also, if no one is in the room, then the student sits at seat number 0.)

Return a class ExamRoom(int N) that exposes two functions: ExamRoom.seat() returning an int representing what seat the student sat in, and ExamRoom.leave(int p) representing that the student in seat number p now leaves the room. It is guaranteed that any calls to ExamRoom.leave§ have a student sitting in seat p.

Note:

1 <= N <= 10^9
ExamRoom.seat() and ExamRoom.leave() will be called at most 10^4 times across all test cases.
Calls to ExamRoom.leave§ are guaranteed to have a student currently sitting in seat number p.

示例:

Example 1:

Input: ["ExamRoom","seat","seat","seat","seat","leave","seat"], [[10],[],[],[],[],[4],[]]
Output: [null,0,9,4,2,null,5]
Explanation:
ExamRoom(10) -> null
seat() -> 0, no one is in the room, then the student sits at seat number 0.
seat() -> 9, the student sits at the last seat number 9.
seat() -> 4, the student sits at the last seat number 4.
seat() -> 2, the student sits at the last seat number 2.
leave(4) -> null
seat() -> 5, the student sits at the last seat number 5.

​​​​​​​

解答1

第一种方法用一个vector来存储就座人的座位号,每次就座的时候,遍历数组找到最大的座位间隔,然后在这个间隔的中间位置就座。

离座的时候只需从vector中删除这个座位号即可。这个算法复杂度为线性的。

代码1

class ExamRoom {int num = 0;
vector<int > row;
public:ExamRoom(int N) {num = N;}int seat() {if (row.size() == 0) {row.push_back(0);return 0;}int d = max(row[0], num - 1 - row[row.size() - 1]);for (int i = 1;i < row.size(); i ++) {d = max(d, (row[i] - row[i - 1]) / 2);}if (d == row[0]) {row.insert(row.begin(), 0);return 0;}else {for (int i = 1; i < row.size(); i++) {if ((row[i] - row[i - 1]) / 2 == d) {row.insert(row.begin() + i, (row[i] + row[i - 1]) / 2);return row[i];}}}row.push_back(num - 1);return num - 1;}void leave(int p) {for (int i = 0; i < row.size(); i++) {if (row[i] == p)row.erase(row.begin() + i);}}
};

解答2

第二种想法算法复杂度为 O ( l o g n ) O(logn) O(logn),在全局中maintain一个set数组,里面按照座位间隔从大到小排列,每次就座的时候就把这个set数据的第一个位置的间隔拿掉,然后将这个间隔一分为二再插入到这个set数据中。

在离座的时候,在set数组里面找到离座的人涉及到的两个间隔,把这两个间隔合并之后再插入到set中就完成了离座。

代码2

struct IntV
{static int N;int l, r;IntV(int l, int r) : l(l), r(r) {};int getDistance() const {if (l == 0) return r;if (r == N - 1) return N - 1 - l;if (r < l) return -1;else return (r - l) / 2;       } int getInsertPoint() const {if (l == 0) return 0;if (r == N  - 1) return N - 1;else return (l + r) / 2; }int operator < (const IntV& a) const {int d1 = getDistance();int d2 = a.getDistance();if(d1 != d2) return d1 > d2;return l < a.l;}
};
int IntV :: N = 0;
class ExamRoom{public:set<IntV> interval;map<int, int> r2l, l2r;ExamRoom(int N) {IntV::N = N;interval.clear(); l2r.clear(); r2l.clear();interval.insert(IntV(0, N - 1));l2r[0] = N - 1;r2l[N -1] = 0;}int seat() {auto cur = *(interval.begin());interval.erase(interval.begin());int pos = cur.getInsertPoint();cout << pos;interval.insert(IntV(cur.l, pos - 1));interval.insert(IntV(pos + 1, cur.r));l2r[cur.l] = pos - 1;r2l[pos - 1] = cur.l;l2r[pos + 1] = cur.r;r2l[cur.r] = pos + 1;return pos;}void leave(int p) {auto r = l2r[p + 1];auto l = r2l[p - 1];interval.erase(IntV(l, p - 1));interval.erase(IntV(p + 1, r));interval.insert(IntV(l, r));l2r[l] = r;r2l[r] = l;r2l.erase(p - 1);l2r.erase(p + 1);}
};

Leetcode 855. Exam Room 考场就座:提供两种解法相关推荐

  1. 20200120:(leetcode)盛最多水的容器 两种解法

    盛最多水的容器 题目 基本思路 代码实现 题目 给定 n 个非负整数 a1,a2,-,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ...

  2. leetcode 73 矩阵置零 C++ 两种解法

    leetcode 73 两种解法~~,没有一个是我想出来的,哈哈~~ one class Solution {public:void setZeroes(vector<vector<int ...

  3. usaco Ordered Fractions 顺序的分数(两种解法)

    这题很好玩,这里有两种解法. 第一种我自己写的,先找到所有的既约真分数,然后写了一个cmp函数进行排序最后输出.我写的时候还在想这章不是搜索吗这跟搜索关系不大吧,难道是怕我们思维定式化故意出的题不是搜 ...

  4. 约瑟夫环问题的两种解法(详解)

    约瑟夫环问题的两种解法(详解) 题目: Josephus有过的故事:39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓.于是决定了自杀方式,41个人排成一个圆 ...

  5. 牛客--追债之旅 两种解法

    文章目录 第一种 第二种: 一共两种解法,所以即便你不会最短路,也可以做,甚至爆搜+剪枝的时间和空间消耗小于最短路做法. 第一种 题意: 小明现在要追讨一笔债务,已知有n座城市,每个城市都有编号,城市 ...

  6. 北林oj-算法设计与分析-Line up in the canteen(两种解法,附思路)

    描述 One day, there is a kind of new delicious food from one of the windows in the canteen. All studen ...

  7. 洛谷——P1597 语句解析(两种解法)

    P1597 语句解析(两种解法) 题目背景 木有背景-- 题目描述 一串长度不超过 255 的 PASCAL 语言代码,只有 a,b,c 3 个变量,而且只有赋值语句,赋值只能是一个一位的数字或一个变 ...

  8. 整数拆分的两种解法(已完成)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 整数拆分 ...

  9. 动态规划——钢筋切割问题的两种解法解析

    动态规划问题--钢筋切割问题的两种解法解析@TOC 钢筋切割问题: 对于这个问题的两种解法 先来个官方点的解法说明: 我对两种解法的个人理解 第一种解法: 这种解法就是把先钢筋分成两部分,分别记为 i ...

最新文章

  1. 一分钟详解点云配准ICP方法
  2. ideal中如何添加几个不同的项目在同一个idea页面显示(同一个窗口显示多个工程)...
  3. Php基础数学运算篇
  4. 高考学文的能报计算机吗,高考志愿填报时,文科生能申报计算机类相关专业吗?...
  5. hdu 1232 畅通工程
  6. JVM快速调优手册v1.0
  7. CISA:很多受害者和 SolarWinds 之间并不直接相关
  8. 动手设计 CPU(二)—— 微程序控制的运算器
  9. Excel函数大全-04数据库函数
  10. qemu-nbd挂载虚拟机镜像文件系统
  11. px4讲解(一)历史起源
  12. itunes store服务中断_Apple目前正在经历App Store iTunes Store和Mac App Store的中断
  13. CMD指令-连接局域网主机
  14. 《软件工程》-用户界面设计
  15. boss网人脸识别认证_老来网社保认证官网版app下载
  16. c #点击按钮下载excel文件
  17. 刀具、砂轮的过程监视和控制系统
  18. 多域单点登录SSO系统的实现
  19. JavaScript 原型链总结(一)
  20. 服务于离群点检测的无监督特征选择值-特征层次耦合模型

热门文章

  1. 算法基础之差分 学习笔记
  2. android 主屏幕,如何重置Android主屏幕返回到默认启动
  3. Linux·主流嵌入式操作系统(RTOS)
  4. 用于Android系统的pango + cairo交叉编译
  5. DTM DEM DSM介绍
  6. [软件人生]士兵突击和亮剑的差别对话
  7. 双端 Diff 算法原理解析及 snabbdom 简单实现
  8. 中兴二层交换机的MAC地址学习
  9. 企业微信小程序可用存储空间不足_如何用微信“小程序商城+企业微信”,搭建企业智慧新零售系统?...
  10. 小米手机安卓手机nfc使用天府通教程及使用方法