Leetcode考场就坐
Posted 梦想闹钟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode考场就坐相关的知识,希望对你有一定的参考价值。
我的解法:
1.考虑极端情况,无人就座,只有1人就座且(坐在左边,中间,最右边),只剩下最左边和最右边的座位等等
2.想的是查找最大的间隔,如果间隔两端都有人那么就坐中间,如果间隔左边没人坐左边,左边有人右边无人坐右边
3.如果间隔大于1/2总长度就可以跳出了,后面的间隔不会更大了
class ExamRoom:
def __init__(self, n: int):
self.seat_list=[]
self.seat_set=set()
self.left=0
self.right=0
self.n=n
def seat(self) -> int:
n=self.n
if self.seat_list==[]:
self.seat_list.append(0)
self.seat_set.add(0)
return 0
if len(self.seat_set)>=n-2 and 0 not in self.seat_set:
self.seat_list.insert(0,0)
self.seat_set.add(0)
return 0
last=-1
max_gap=n-1-self.seat_list[-1]-1
if max_gap<0:
max_gap=0
left=-1
right=n
half_gap=n//2
insert_loc=0
for student in range(0,len(self.seat_list)):
gap=self.seat_list[student]-last
if gap//2>max_gap//2:
max_gap=gap
left=last
right=self.seat_list[student]
insert_loc=student
if max_gap>half_gap:
break
last=self.seat_list[student]
if left in self.seat_set and right in self.seat_set:
new_seat=(left+right)//2
self.seat_list.insert(insert_loc,new_seat)
self.seat_set.add(new_seat)
return new_seat
if n-1 not in self.seat_set:
self.seat_list.append(n-1)
self.seat_set.add(n-1)
return n-1
self.seat_list.insert(0,0)
self.seat_set.add(0)
return 0
def leave(self, p: int) -> None:
self.seat_list.remove(p)
self.seat_set.remove(p)
标准解法:
class ExamRoom:
def __init__(self, n: int):
self.heap_info = []
self.last = n - 1
heappush(self.heap_info, [-self.last, -1, self.last + 1])
def seat(self) -> int:
gap, left, right = heappop(self.heap_info)
if left < 0:
if right > self.last:
heappush(self.heap_info, [-self.last, 0, right])
elif right > 1:
heappush(self.heap_info, [-(right >> 1), 0, right])
return 0
elif right > self.last:
if gap < -1:
heappush(self.heap_info, [-(-gap >> 1), left, self.last])
return self.last
else:
seat_idx = left - gap
if gap < -1:
heappush(self.heap_info, [-(-gap >> 1), left, seat_idx])
heappush(self.heap_info, [-((right - seat_idx) >> 1), seat_idx, right])
elif left + 3 == right:
heappush(self.heap_info, [-1, seat_idx, right])
return seat_idx
def leave(self, p: int) -> None:
if p == 0:
right = 1
for i in range(len(self.heap_info)):
if self.heap_info[i][1] == 0:
_, _, right = self.heap_info.pop(i)
break
heappush(self.heap_info, [-right, -1, right])
elif p == self.last:
left = p - 1
for i in range(len(self.heap_info)):
if self.heap_info[i][2] == self.last:
_, left, _ = self.heap_info.pop(i)
break
heappush(self.heap_info, [left - self.last, left, self.last + 1])
else:
cnt = 0
left, right = p - 1, p + 1
for i in range(len(self.heap_info) - 1, -1, -1):
if self.heap_info[i][1] == p:
_, _, right = self.heap_info.pop(i)
if cnt == 1:
break
cnt = 1
elif self.heap_info[i][2] == p:
_, left, _ = self.heap_info.pop(i)
if cnt == 1:
break
cnt = 1
if left < 0:
gap = right
elif right > self.last:
gap = self.last - left
else:
gap = (right - left) >> 1
heappush(self.heap_info, [-gap, left, right])
return None
python的heappush和heappop:
1.heappush(heap,item)建立大、小根堆
heapq.heappush()是往堆中添加新值,此时自动建立了小根堆
不能直接建立大跟堆,所以每次push时给元素加一个负号(即取相反数),此时最小值变最大值,反之亦然,那么实际上的最大值就可以处于堆顶了,返回时再取负即可。
2.heapq.heappop()从堆中弹出并返回最小的值
普通list(即并没有进行heapify等操作的list),对他进行heappop操作并不会弹出list中最小的值,而是弹出第一个值。
对于小跟堆,会依次弹出最小的值。
x>>1相当于快速的x//2
原文链接:https://blog.csdn.net/qq_38022469/article/details/123851001
其他解答:
区间的左右两边用有序列表存储,元素是一个元组,排序的key是计算距离的负数,这样可以确保大的值排在前面,第二个排序依据是x[0]就是区间的左边位置,确保先坐序号小的
这样seat的时候就相当于删除了原来的区间,把其分割为两个新的区间。
两个字典存放的是当前学生左右两边的学生,方便删除的时候合并区间,这个比较好懂一些
from sortedcontainers import SortedList
class ExamRoom:
def __init__(self, n: int):
def dist(x):
l, r = x
return r - l - 1 if l == -1 or r == n else (r - l) >> 1
self.n = n
self.ts = SortedList(key=lambda x: (-dist(x), x[0]))
self.left =
self.right =
self.add((-1, n))
def seat(self) -> int:
s = self.ts[0]
p = (s[0] + s[1]) >> 1
if s[0] == -1:
p = 0
elif s[1] == self.n:
p = self.n - 1
self.delete(s)
self.add((s[0], p))
self.add((p, s[1]))
return p
def leave(self, p: int) -> None:
l, r = self.left[p], self.right[p]
self.delete((l, p))
self.delete((p, r))
self.add((l, r))
def add(self, s):
self.ts.add(s)
self.left[s[1]] = s[0]
self.right[s[0]] = s[1]
def delete(self, s):
self.ts.remove(s)
self.left.pop(s[1])
self.right.pop(s[0])
作者:lcbin
链接:https://leetcode.cn/problems/exam-room/solution/by-lcbin-tstp/
来源:力扣(LeetCode)
noip2017总结
day-1:在郑州,和蛤实验一起考试玩,考完试之后坐上了回邯郸的火车,打了一路炉石传说。
day0:大早上就坐上了秦皇岛的火车,中午才到,真尼玛热,我穿那么厚。然后就在宾馆待着,一种说不出来的滋味,心里面特别慌,感觉要GG了。下午去了燕山大学看考场,找了半天才找到一个机子坐下来,结果又被撵走了,,,连a+b都没码完,实在佩服码主席树的dalao。然后回宾馆胡乱吃了点饭早早睡下了,那的炸鸡真难吃。
day1:我起的早,6点多就到宾馆下面了,宾馆全是人,但全是hzoi得人。。。我们的人还没睡醒。。。7点多人才凑齐,匆(man)匆忙(you)忙赶到燕山大学,在食堂吃了点饭,,真心跟我校食堂没得比。内心一直是崩溃的,同学给我买了瓶水然后就进考场了。我第一次参加这种大型比赛,全程一直紧紧张张的,一直害怕文件名等白痴错误,甚至害怕文件夹放错。
t1,一看就感觉是gcd相关的,然而并不会。
t2,前几天在郑州做过一个比这个恶心多的模拟。。应该不难写?
t3,啥jb玩意
再回头看t1,先写个背包找找规律?然后我就发现了一些奇奇怪怪的性质,然后就随便加进了gcd的过程中,和样例一测,差1,emmmm,减个1试试?诶呀过啦,样例二,也过啦,对拍一会,全过啦,嗯应该是对了。
看t2,耐心的模拟,,读入坑了我半天,,好在样例1过了,2就直接过掉了,也没办法对拍,就去看t3了。
t3,我。。好像会?脑子很混乱,然后就打算按自己意思写,一看时间就1个多小时了,应该是写不完了,不如拿70?写完之后还剩40分钟吧,然后呢,随便出一组数据就过不去了,突然开始慌了。。。然后又推翻了自己的算法,于是匆匆忙忙打了个爆搜上去,,应该有10分了吧。
期望210?
考完试之后就去宾馆窝着,突然有人说要去海边看看,然后就跟他们去了。真尼玛冷。差点迷路了。
回来的路上,wjh跟我说t2变量名不一定是一个小写字母。。。逗我???我当时就慌了,瞬间摩托变单车?110了?
然后心态就不好了,,于是去吃东西,去燕大对面那个小吃一条街,味道好一般。。。
然后看了会王师傅直播就睡觉了。
day2:换考场了。。。我都不知道!
坚决不去燕大吃饭了,于是在宾馆门口找了个卖包子的。我可能适应不了这里的饮食。。。我跟他们说昨天t2的事,他们表示题目中明确说明是单个字母了。感觉好受点了?
平淡地迎接下一场考试,旁边坐着的是之前认识的一个唐山一中的小哥qwq
t1:我曹?被mk奶中了?三维几何?woc?这么难?就知道今天题简单不了
t2:题目啥意思?没看懂。。。
t3:70分?
t1:这么简单。。。?好像会炸ll?用ull?负数怎么搞啊(现在想想当时真是傻。。)总不能让我写高精吧?不写不写,ll好了。
t2:树的情况好像很好拿?
t3:傻jb玩意,估计也就30能拿了。。。
写完150分之后,还有两个小时吧。。。总不能闲着,期望360肯定要完,不如继续看看?、
t2:40分好像随便搜一搜就出来了?
t3:q<=500好像很简单?
写了会对拍了会大概就1小时了。
t2弃疗了,肯定是个状压相关,完全没思路。
t3的另外20能不能拿到?
想了半天依旧没啥思路。。。开始检查好了。。。于是盯着屏幕看了40分钟。。。
然后我发现我校大部分也就150。。突然感谢我自己多想了一会蒙到190?
那么。。这两天期望得分是400么?
感觉还不错。。。。
然后回宾馆,收拾东西准备回家。
hz的人也在楼下
“我这次最多考到430了”
“t2好简单”
“t3也不难”
瞬间受到打击了。感觉完蛋了。
后来知道t1要ull,跟负数没个毛关系,,仔细一想,,是啊。。t1gg了。。
然后就坐上了回家的火车。
退役狗退役狗,去打炉石啦
然后老马不知道从哪搞来了民间数据,我看了看,民间跑了410?是有多水啊。。。但是貌似排名还不错?20名左右,前面一个石二,一个衡二,其余,,hz包揽。
然后听老马说我还有希望,如果官方和民间差不多的话,因为1/3政策,hz最多5人。顿时有了信心?
其他人都炸了。。。wjh因为day1t2大小写gg,其他人也都是各种不同程度的gg,我校第二名是一个高一的。。顿时。。。(虽然我也得叫他一声前辈,他们初三就在弄了)
感觉心情还不错?回学校之后又用了清北学堂的数据跑了一下,400,大概就这样了?380分左右吧。应该就这样了。
官方数据还没有给。我也不知道考的到底咋样,我还不想滚粗qwq。
总的来说也算没什么遗憾吧,就算滚粗了也只能怪自己太弱了,我能拿的分都拿满了,其他的只能是水平问题了。
希望我还能步入省选的赛场。
ps:希望不要官方数据GGqwq
以上是关于Leetcode考场就坐的主要内容,如果未能解决你的问题,请参考以下文章
算法 Notes|LeetCode 1. 两数之和 - easy