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

前端与算法 leetcode 1. 两数之和

算法 Notes|LeetCode 1. 两数之和 - easy

每日算法/刷穿 LeetCode9. 回文数(简单)

[算法] LeetCode 1.两数之和

每日算法/刷穿 LeetCode15. 三数之和(中等)