Leetcode考场就坐
我的解法:
1.考慮極端情況,無人就座,只有1人就座且(坐在左邊,中間,最右邊),只剩下最左邊和最右邊的座位等等
2.想的是查找最大的間隔,如果間隔兩端都有人那么就坐中間,如果間隔左邊沒人坐左邊,左邊有人右邊無人坐右邊
3.如果間隔大于1/2總長度就可以跳出了,后面的間隔不會更大了
標準解法:
class ExamRoom:def __init__(self, n: int): self.heap_info = [] self.last = n - 1heappush(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 0elif right > self.last:if gap < -1:heappush(self.heap_info, [-(-gap >> 1), left, self.last]) return self.lastelse:seat_idx = left - gapif 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_idxdef leave(self, p: int) -> None:if p == 0:right = 1for i in range(len(self.heap_info)):if self.heap_info[i][1] == 0:_, _, right = self.heap_info.pop(i)breakheappush(self.heap_info, [-right, -1, right]) elif p == self.last:left = p - 1for i in range(len(self.heap_info)):if self.heap_info[i][2] == self.last:_, left, _ = self.heap_info.pop(i)breakheappush(self.heap_info, [left - self.last, left, self.last + 1]) else:cnt = 0left, right = p - 1, p + 1for 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:breakcnt = 1 elif self.heap_info[i][2] == p:_, left, _ = self.heap_info.pop(i)if cnt == 1:breakcnt = 1 if left < 0:gap = rightelif right > self.last:gap = self.last - leftelse:gap = (right - left) >> 1heappush(self.heap_info, [-gap, left, right]) return Nonepython的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的時候就相當于刪除了原來的區間,把其分割為兩個新的區間。
兩個字典存放的是當前學生左右兩邊的學生,方便刪除的時候合并區間,這個比較好懂一些
作者:lcbin
鏈接:https://leetcode.cn/problems/exam-room/solution/by-lcbin-tstp/
來源:力扣(LeetCode)
總結
以上是生活随笔為你收集整理的Leetcode考场就坐的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: String problem and S
- 下一篇: java - StringBuilder