Leetcode考场就坐
我的解法:
1.考慮極端情況,無(wú)人就座,只有1人就座且(坐在左邊,中間,最右邊),只剩下最左邊和最右邊的座位等等
2.想的是查找最大的間隔,如果間隔兩端都有人那么就坐中間,如果間隔左邊沒(méi)人坐左邊,左邊有人右邊無(wú)人坐右邊
3.如果間隔大于1/2總長(zhǎng)度就可以跳出了,后面的間隔不會(huì)更大了
標(biāo)準(zhǔn)解法:
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()是往堆中添加新值,此時(shí)自動(dòng)建立了小根堆
不能直接建立大跟堆,所以每次push時(shí)給元素加一個(gè)負(fù)號(hào)(即取相反數(shù)),此時(shí)最小值變最大值,反之亦然,那么實(shí)際上的最大值就可以處于堆頂了,返回時(shí)再取負(fù)即可。
2.heapq.heappop()從堆中彈出并返回最小的值
普通list(即并沒(méi)有進(jìn)行heapify等操作的list),對(duì)他進(jìn)行heappop操作并不會(huì)彈出list中最小的值,而是彈出第一個(gè)值。
對(duì)于小跟堆,會(huì)依次彈出最小的值。
x>>1相當(dāng)于快速的x//2
原文鏈接:https://blog.csdn.net/qq_38022469/article/details/123851001
其他解答:
區(qū)間的左右兩邊用有序列表存儲(chǔ),元素是一個(gè)元組,排序的key是計(jì)算距離的負(fù)數(shù),這樣可以確保大的值排在前面,第二個(gè)排序依據(jù)是x[0]就是區(qū)間的左邊位置,確保先坐序號(hào)小的
這樣seat的時(shí)候就相當(dāng)于刪除了原來(lái)的區(qū)間,把其分割為兩個(gè)新的區(qū)間。
兩個(gè)字典存放的是當(dāng)前學(xué)生左右兩邊的學(xué)生,方便刪除的時(shí)候合并區(qū)間,這個(gè)比較好懂一些
作者:lcbin
鏈接:https://leetcode.cn/problems/exam-room/solution/by-lcbin-tstp/
來(lái)源:力扣(LeetCode)
總結(jié)
以上是生活随笔為你收集整理的Leetcode考场就坐的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: String problem and S
- 下一篇: java - StringBuilder