-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdinner_plate_stacks.py
120 lines (94 loc) · 4.04 KB
/
dinner_plate_stacks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
'''
You have an infinite number of stacks arranged in a row and numbered (left to right) from 0, each of the stacks has the same maximum capacity.
Implement the DinnerPlates class:
DinnerPlates(int capacity) Initializes the object with the maximum capacity of the stacks capacity.
void push(int val) Pushes the given integer val into the leftmost stack with a size less than capacity.
int pop() Returns the value at the top of the rightmost non-empty stack and removes it from that stack, and returns -1 if all the stacks are empty.
int popAtStack(int index) Returns the value at the top of the stack with the given index index and removes it from that stack or returns -1 if the stack with that given index is empty.
'''
class DinnerPlates:
def __init__(self, capacity: int):
self.size = capacity
self.arr = []
self.leftmost = []
self.rightmost = []
self.nonempty = set()
self.presentInLeftmost = set()
def push(self, val: int) -> None:
if self.leftmost:
top = self.leftmost[0]
self.arr[top].append(val)
if len(self.arr[top]) == self.size:
self.presentInLeftmost.remove(top)
heappop(self.leftmost)
if top not in self.nonempty:
self.nonempty.add(top)
heappush(self.rightmost, -top)
else:
self.arr.append([val])
curr = len(self.arr) - 1
if len(self.arr[-1]) < self.size:
self.presentInLeftmost.add(curr)
heappush(self.leftmost, curr)
heappush(self.rightmost, -curr)
self.nonempty.add(curr)
def pop(self) -> int:
if not self.rightmost:
return -1
flag = 0
while self.rightmost:
top = -self.rightmost[0]
if top in self.nonempty:
flag = 1
break
heappop(self.rightmost)
if flag == 0:
return -1
ans = self.arr[top].pop()
if len(self.arr[top]) == 0:
self.nonempty.remove(top)
heappop(self.rightmost)
if top not in self.presentInLeftmost:
self.presentInLeftmost.add(top)
heappush(self.leftmost, top)
return ans
def popAtStack(self, index: int) -> int:
if index > len(self.arr) - 1 or len(self.arr[index]) == 0:
return -1
ans = self.arr[index].pop()
if len(self.arr[index]) == 0:
self.nonempty.remove(index)
if index not in self.presentInLeftmost:
self.presentInLeftmost.add(index)
heappush(self.leftmost, index)
return ans
# Your DinnerPlates object will be instantiated and called as such:
# obj = DinnerPlates(capacity)
# obj.push(val)
# param_2 = obj.pop()
# param_3 = obj.popAtStack(index)
-----------------------------------------------------------------------------------------------------------------------
class DinnerPlates:
def __init__(self, capacity: int):
self.cpty = capacity
self.pq = [] # min heap of non-full stacks
self.stacks = []
def push(self, val: int) -> None:
while self.pq:
k = heappop(self.pq)
if k < len(self.stacks): break
else:
k = len(self.stacks)
self.stacks.append([])
self.stacks[k].append(val)
if len(self.stacks[k]) < self.cpty: heappush(self.pq, k)
def pop(self) -> int:
while self.stacks and not self.stacks[-1]: self.stacks.pop()
if self.stacks:
if len(self.stacks[-1]) == self.cpty: heappush(self.pq, len(self.stacks)-1)
return self.stacks[-1].pop()
return -1
def popAtStack(self, index: int) -> int:
if index >= len(self.stacks) or not self.stacks[index]: return -1
if len(self.stacks[index]) == self.cpty: heappush(self.pq, index)
return self.stacks[index].pop()