Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6182d5d

Browse files
committed
feat: add solutions to lc problem: No.1172
No.1172.Dinner Plate Stacks
1 parent aebad32 commit 6182d5d

File tree

6 files changed

+650
-0
lines changed

6 files changed

+650
-0
lines changed

‎solution/1100-1199/1172.Dinner Plate Stacks/README.md‎

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,22 +77,258 @@ D.pop() // 返回 -1。仍然没有栈。
7777

7878
<!-- 这里可写通用的实现逻辑 -->
7979

80+
**方法一:栈数组 + 有序集合**
81+
82+
我们定义以下数据结构或变量:
83+
84+
- `capacity`:每个栈的容量;
85+
- `stacks`:栈数组,用于存储所有的栈,其中每个栈的最大容量都是 `capacity`;
86+
- `not_full`:有序集合,用于存储所有未满的栈在栈数组中的下标。
87+
88+
对于 `push(val)` 操作:
89+
90+
- 我们首先判断 `not_full` 是否为空,如果为空,则说明没有未满的栈,需要新建一个栈,然后将 `val` 压入该栈中,此时判断容量 `capacity` 是否大于 1ドル,ドル如果大于 1ドル,ドル则将该栈的下标加入 `not_full` 中。
91+
- 如果 `not_full` 不为空,则说明有未满的栈,我们取出 `not_full` 中最小的下标 `index`,将 `val` 压入 `stacks[index]` 中,此时如果 `stacks[index]` 的容量等于 `capacity`,则将 `index``not_full` 中删除。
92+
93+
对于 `popAtStack(index)` 操作:
94+
95+
- 我们首先判断 `index` 是否在 `stacks` 的下标范围内,如果不在,则直接返回 $-1$。如果 `stacks[index]` 为空,同样直接返回 $-1$。
96+
- 如果 `stacks[index]` 不为空,则取出 `stacks[index]` 的栈顶元素 `val`,并将其从栈中删除。如果 `index` 等于 `stacks` 的长度减 1ドル,ドル则说明 `stacks[index]` 是最后一个栈,如果此时 `stacks[index]` 为空,我们循环将 `index``stacks` 中删除,并且将 `index``not_full` 中删除,直到 `stacks[index]` 不为空或者 `stacks` 为空为止。否则,如果 `stacks[index]` 不是最后一个栈,我们将 `index` 加入 `not_full` 中。
97+
- 最后返回 `val`
98+
99+
对于 `pop()` 操作:
100+
101+
- 我们直接调用 `popAtStack(stacks.length - 1)` 即可。
102+
103+
时间复杂度 $(n \times \log n),ドル空间复杂度 $O(n)$。其中 $n$ 为操作次数。
104+
80105
<!-- tabs:start -->
81106

82107
### **Python3**
83108

84109
<!-- 这里可写当前语言的特殊实现逻辑 -->
85110

86111
```python
112+
from sortedcontainers import SortedSet
113+
114+
115+
class DinnerPlates:
116+
def __init__(self, capacity: int):
117+
self.capacity = capacity
118+
self.stacks = []
119+
self.not_full = SortedSet()
120+
121+
def push(self, val: int) -> None:
122+
if not self.not_full:
123+
self.stacks.append([val])
124+
if self.capacity > 1:
125+
self.not_full.add(len(self.stacks) - 1)
126+
else:
127+
index = self.not_full[0]
128+
self.stacks[index].append(val)
129+
if len(self.stacks[index]) == self.capacity:
130+
self.not_full.discard(index)
131+
132+
def pop(self) -> int:
133+
return self.popAtStack(len(self.stacks) - 1)
87134

135+
def popAtStack(self, index: int) -> int:
136+
if index < 0 or index >= len(self.stacks) or not self.stacks[index]:
137+
return -1
138+
val = self.stacks[index].pop()
139+
if index == len(self.stacks) - 1 and not self.stacks[-1]:
140+
while self.stacks and not self.stacks[-1]:
141+
self.not_full.discard(len(self.stacks) - 1)
142+
self.stacks.pop()
143+
else:
144+
self.not_full.add(index)
145+
return val
146+
147+
148+
# Your DinnerPlates object will be instantiated and called as such:
149+
# obj = DinnerPlates(capacity)
150+
# obj.push(val)
151+
# param_2 = obj.pop()
152+
# param_3 = obj.popAtStack(index)
88153
```
89154

90155
### **Java**
91156

92157
<!-- 这里可写当前语言的特殊实现逻辑 -->
93158

94159
```java
160+
class DinnerPlates {
161+
private int capacity;
162+
private List<Deque<Integer>> stacks = new ArrayList<>();
163+
private TreeSet<Integer> notFull = new TreeSet<>();
164+
165+
public DinnerPlates(int capacity) {
166+
this.capacity = capacity;
167+
}
168+
169+
public void push(int val) {
170+
if (notFull.isEmpty()) {
171+
stacks.add(new ArrayDeque<>());
172+
stacks.get(stacks.size() - 1).push(val);
173+
if (capacity > 1) {
174+
notFull.add(stacks.size() - 1);
175+
}
176+
} else {
177+
int index = notFull.first();
178+
stacks.get(index).push(val);
179+
if (stacks.get(index).size() == capacity) {
180+
notFull.pollFirst();
181+
}
182+
}
183+
}
184+
185+
public int pop() {
186+
return popAtStack(stacks.size() - 1);
187+
}
188+
189+
public int popAtStack(int index) {
190+
if (index < 0 || index >= stacks.size() || stacks.get(index).isEmpty()) {
191+
return -1;
192+
}
193+
int val = stacks.get(index).pop();
194+
if (index == stacks.size() - 1 && stacks.get(stacks.size() - 1).isEmpty()) {
195+
while (!stacks.isEmpty() && stacks.get(stacks.size() - 1).isEmpty()) {
196+
notFull.remove(stacks.size() - 1);
197+
stacks.remove(stacks.size() - 1);
198+
}
199+
} else {
200+
notFull.add(index);
201+
}
202+
return val;
203+
}
204+
}
205+
206+
/**
207+
* Your DinnerPlates object will be instantiated and called as such:
208+
* DinnerPlates obj = new DinnerPlates(capacity);
209+
* obj.push(val);
210+
* int param_2 = obj.pop();
211+
* int param_3 = obj.popAtStack(index);
212+
*/
213+
```
214+
215+
### **C++**
216+
217+
```cpp
218+
class DinnerPlates {
219+
public:
220+
DinnerPlates(int capacity) {
221+
this->capacity = capacity;
222+
}
223+
224+
void push(int val) {
225+
if (notFull.empty()) {
226+
stacks.emplace_back(stack<int>());
227+
stacks.back().push(val);
228+
if (capacity > 1) {
229+
notFull.insert(stacks.size() - 1);
230+
}
231+
} else {
232+
int index = *notFull.begin();
233+
stacks[index].push(val);
234+
if (stacks[index].size() == capacity) {
235+
notFull.erase(index);
236+
}
237+
}
238+
}
239+
240+
int pop() {
241+
return popAtStack(stacks.size() - 1);
242+
}
243+
244+
int popAtStack(int index) {
245+
if (index < 0 || index >= stacks.size() || stacks[index].empty()) {
246+
return -1;
247+
}
248+
int val = stacks[index].top();
249+
stacks[index].pop();
250+
if (index == stacks.size() - 1 && stacks[index].empty()) {
251+
while (!stacks.empty() && stacks.back().empty()) {
252+
notFull.erase(stacks.size() - 1);
253+
stacks.pop_back();
254+
}
255+
} else {
256+
notFull.insert(index);
257+
}
258+
return val;
259+
}
260+
261+
private:
262+
int capacity;
263+
vector<stack<int>> stacks;
264+
set<int> notFull;
265+
};
266+
267+
/**
268+
* Your DinnerPlates object will be instantiated and called as such:
269+
* DinnerPlates* obj = new DinnerPlates(capacity);
270+
* obj->push(val);
271+
* int param_2 = obj->pop();
272+
* int param_3 = obj->popAtStack(index);
273+
*/
274+
```
275+
276+
### **Go**
277+
278+
```go
279+
type DinnerPlates struct {
280+
capacity int
281+
stacks [][]int
282+
notFull *redblacktree.Tree
283+
}
284+
285+
func Constructor(capacity int) DinnerPlates {
286+
return DinnerPlates{capacity: capacity, notFull: redblacktree.NewWithIntComparator()}
287+
}
288+
289+
func (this *DinnerPlates) Push(val int) {
290+
if this.notFull.Size() == 0 {
291+
this.stacks = append(this.stacks, []int{val})
292+
if this.capacity > 1 {
293+
this.notFull.Put(len(this.stacks)-1, nil)
294+
}
295+
} else {
296+
index, _ := this.notFull.Left().Key.(int)
297+
this.stacks[index] = append(this.stacks[index], val)
298+
if len(this.stacks[index]) == this.capacity {
299+
this.notFull.Remove(index)
300+
}
301+
}
302+
}
303+
304+
func (this *DinnerPlates) Pop() int {
305+
return this.PopAtStack(len(this.stacks) - 1)
306+
}
307+
308+
func (this *DinnerPlates) PopAtStack(index int) int {
309+
if index < 0 || index >= len(this.stacks) || len(this.stacks[index]) == 0 {
310+
return -1
311+
}
312+
val := this.stacks[index][len(this.stacks[index])-1]
313+
this.stacks[index] = this.stacks[index][:len(this.stacks[index])-1]
314+
if index == len(this.stacks)-1 && len(this.stacks[index]) == 0 {
315+
for len(this.stacks) > 0 && len(this.stacks[len(this.stacks)-1]) == 0 {
316+
this.notFull.Remove(len(this.stacks) - 1)
317+
this.stacks = this.stacks[:len(this.stacks)-1]
318+
}
319+
} else {
320+
this.notFull.Put(index, nil)
321+
}
322+
return val
323+
}
95324

325+
/**
326+
* Your DinnerPlates object will be instantiated and called as such:
327+
* obj := Constructor(capacity);
328+
* obj.Push(val);
329+
* param_2 := obj.Pop();
330+
* param_3 := obj.PopAtStack(index);
331+
*/
96332
```
97333

98334
### **...**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /