forked from wisdompeak/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
060b65f
commit 716c998
Showing
1 changed file
with
7 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
### 855.Exam-Room.cpp | ||
|
||
此题考虑什么样的数据结构最合适。我们需要存放什么呢?其实只要存放每个人的位置就可以了。人与人的间隔要不要单独存储呢?其实可以不必。线性的数组在这里就足够用了。虽然每次插入位置的搜索是线性的,内存的移动也会费时间,但似乎实际的效率还不错。 | ||
本题比较偷懒的方法就是用有序容器set来盛装所有人的位置。在调用seat()的时候,就用迭代器遍历set的所有元素,查找相邻元素a和b之间的距离```diff=b-a```,那么如果要在这个区间内插入一人,显然只能插在```a+diff/2```这个地方,并且就是```diff/2```. | ||
|
||
每次进来一个人,我们线性扫描现有人的位置,查找最大的间隔。另外,头和尾的间隔需要另行考虑。确定最大间隔,就能确定插入的位置,直接用数组的insert命令即可。 | ||
需要特别注意的是如果set里的第一个元素不是0,那么我们可以选择在0位置插入。同理如果set里的最后一个元素不是n-1,那么我们可以选择在n-1位置插入。这两个地方需要单独处理。 | ||
|
||
在人离开的时候,也是直接用lower_bound确定位置的迭代器,再删除迭代器即可。 | ||
最终我们选择全局“离最近的人的最远距离”的最优解来安排新人的位置。所以seat()的时间复杂度是o(n). | ||
|
||
对于leave(int p),则简单多了,可以直接o(1)从set里删除即可。 | ||
|
||
[Leetcode Link](https://leetcode.com/problems/exam-room) | ||
当然本题还有复杂的做法,就是将所有连续的空座区间按照“插入后离最近的人的最远距离”放入优先队列。这样我们可以log(n)的时间实现seat()。但是对于leave(p)的操作,似乎就只能靠o(n)来遍历再删除了。 | ||
|
||
[Leetcode Link](https://leetcode.com/problems/exam-room) |