Skip to content

Commit 715858d

Browse files
authored
Merge pull request #1331 from 0xff-dev/1172
Add solution and test-cases for problem 1172
2 parents 68495e2 + 7845ccb commit 715858d

File tree

3 files changed

+254
-28
lines changed

3 files changed

+254
-28
lines changed

leetcode/1101-1200/1172.Dinner-Plate-Stacks/README.md

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,58 @@
11
# [1172.Dinner Plate Stacks][title]
22

3-
> [!WARNING|style:flat]
4-
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
5-
63
## Description
4+
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.
75

8-
**Example 1:**
9-
10-
```
11-
Input: a = "11", b = "1"
12-
Output: "100"
13-
```
6+
Implement the `DinnerPlates` class:
147

15-
## 题意
16-
> ...
8+
- `DinnerPlates(int capacity)` Initializes the object with the maximum capacity of the stacks `capacity`.
9+
- `void push(int val)` Pushes the given integer `val` into the leftmost stack with a size less than `capacity`.
10+
- `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.
11+
- `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.
1712

18-
## 题解
13+
**Example 1:**
1914

20-
### 思路1
21-
> ...
22-
Dinner Plate Stacks
23-
```go
2415
```
25-
16+
Input
17+
["DinnerPlates", "push", "push", "push", "push", "push", "popAtStack", "push", "push", "popAtStack", "popAtStack", "pop", "pop", "pop", "pop", "pop"]
18+
[[2], [1], [2], [3], [4], [5], [0], [20], [21], [0], [2], [], [], [], [], []]
19+
Output
20+
[null, null, null, null, null, null, 2, null, null, 20, 21, 5, 4, 3, 1, -1]
21+
22+
Explanation:
23+
DinnerPlates D = DinnerPlates(2); // Initialize with capacity = 2
24+
D.push(1);
25+
D.push(2);
26+
D.push(3);
27+
D.push(4);
28+
D.push(5); // The stacks are now: 2 4
29+
1 3 5
30+
﹈ ﹈ ﹈
31+
D.popAtStack(0); // Returns 2. The stacks are now: 4
32+
1 3 5
33+
﹈ ﹈ ﹈
34+
D.push(20); // The stacks are now: 20 4
35+
1 3 5
36+
﹈ ﹈ ﹈
37+
D.push(21); // The stacks are now: 20 4 21
38+
1 3 5
39+
﹈ ﹈ ﹈
40+
D.popAtStack(0); // Returns 20. The stacks are now: 4 21
41+
1 3 5
42+
﹈ ﹈ ﹈
43+
D.popAtStack(2); // Returns 21. The stacks are now: 4
44+
1 3 5
45+
﹈ ﹈ ﹈
46+
D.pop() // Returns 5. The stacks are now: 4
47+
1 3
48+
﹈ ﹈
49+
D.pop() // Returns 4. The stacks are now: 1 3
50+
﹈ ﹈
51+
D.pop() // Returns 3. The stacks are now: 1
52+
53+
D.pop() // Returns 1. There are no stacks.
54+
D.pop() // Returns -1. There are still no stacks.
55+
```
2656

2757
## 结语
2858

Lines changed: 182 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,186 @@
11
package Solution
22

3-
func Solution(x bool) bool {
3+
import "container/heap"
4+
5+
type heapItem1172 struct {
6+
stack []int
7+
8+
index, sourceIndex int
9+
}
10+
11+
type leftNotFullHeap struct {
12+
data []*heapItem1172
13+
capacity int
14+
}
15+
16+
func (h *leftNotFullHeap) Len() int {
17+
return len(h.data)
18+
}
19+
20+
func (h *leftNotFullHeap) Less(i, j int) bool {
21+
a, b := h.data[i], h.data[j]
22+
la, lb := len(a.stack), len(b.stack)
23+
if la == h.capacity {
24+
return false
25+
}
26+
if lb == h.capacity {
27+
return true
28+
}
29+
return a.sourceIndex < b.sourceIndex
30+
}
31+
32+
func (h *leftNotFullHeap) Swap(i, j int) {
33+
h.data[i], h.data[j] = h.data[j], h.data[i]
34+
h.data[i].index = i
35+
h.data[j].index = j
36+
}
37+
38+
func (h *leftNotFullHeap) Push(x any) {
39+
item := x.(*heapItem1172)
40+
l := len(h.data)
41+
item.index = l
42+
h.data = append(h.data, item)
43+
}
44+
45+
func (h *leftNotFullHeap) Pop() any {
46+
old := h.data
47+
l := len(old)
48+
x := old[l-1]
49+
h.data = old[:l-1]
450
return x
551
}
52+
53+
type rightHeapItem1172 struct {
54+
sourceIndex, index int
55+
}
56+
type rightNotEmptyHeap struct {
57+
data []*rightHeapItem1172
58+
list *[]*heapItem1172
59+
}
60+
61+
func (h *rightNotEmptyHeap) Len() int {
62+
return len(h.data)
63+
}
64+
65+
func (h *rightNotEmptyHeap) Less(i, j int) bool {
66+
a, b := h.data[i], h.data[j]
67+
ia, ib := (*h.list)[a.sourceIndex], (*h.list)[b.sourceIndex]
68+
li, lj := len(ia.stack), len(ib.stack)
69+
if li == 0 && lj == 0 || (li != 0 && lj != 0) {
70+
return a.sourceIndex > b.sourceIndex
71+
}
72+
return li != 0
73+
}
74+
75+
func (h *rightNotEmptyHeap) Swap(i, j int) {
76+
h.data[i], h.data[j] = h.data[j], h.data[i]
77+
h.data[i].index = i
78+
h.data[j].index = j
79+
}
80+
81+
func (h *rightNotEmptyHeap) Push(x any) {
82+
item := x.(*rightHeapItem1172)
83+
item.index = len(h.data)
84+
h.data = append(h.data, item)
85+
}
86+
87+
func (h *rightNotEmptyHeap) Pop() any {
88+
l := len(h.data)
89+
x := h.data[l-1]
90+
h.data = h.data[:l-1]
91+
return x
92+
}
93+
94+
type DinnerPlates struct {
95+
leftNotFull *leftNotFullHeap
96+
rightNotEmpty *rightNotEmptyHeap
97+
capacity int
98+
leftIndies *[]*heapItem1172
99+
100+
rightIndies map[int]*rightHeapItem1172
101+
}
102+
103+
func Constructor(capacity int) DinnerPlates {
104+
indies := make([]*heapItem1172, 0)
105+
return DinnerPlates{
106+
leftNotFull: &leftNotFullHeap{
107+
data: make([]*heapItem1172, 0),
108+
capacity: capacity,
109+
},
110+
rightNotEmpty: &rightNotEmptyHeap{
111+
data: make([]*rightHeapItem1172, 0),
112+
list: &indies,
113+
},
114+
capacity: capacity,
115+
leftIndies: &indies,
116+
rightIndies: make(map[int]*rightHeapItem1172),
117+
}
118+
}
119+
120+
func (this *DinnerPlates) Push(val int) {
121+
if len(this.leftNotFull.data) == 0 || len(this.leftNotFull.data[0].stack) == this.capacity {
122+
sourceIndex := len(this.leftNotFull.data)
123+
leftItem := &heapItem1172{
124+
stack: []int{val},
125+
sourceIndex: sourceIndex,
126+
}
127+
rightItem := &rightHeapItem1172{
128+
sourceIndex: sourceIndex,
129+
}
130+
this.rightIndies[sourceIndex] = rightItem
131+
132+
*this.leftIndies = append(*this.leftIndies, leftItem)
133+
heap.Push(this.leftNotFull, leftItem)
134+
heap.Push(this.rightNotEmpty, rightItem)
135+
return
136+
}
137+
zero := this.leftNotFull.data[0]
138+
zero.stack = append(zero.stack, val)
139+
heap.Fix(this.leftNotFull, 0)
140+
heap.Fix(this.rightNotEmpty, this.rightIndies[zero.sourceIndex].index)
141+
}
142+
143+
func (this *DinnerPlates) Pop() int {
144+
top := this.rightNotEmpty.data[0]
145+
return this.PopAtStack(top.sourceIndex)
146+
}
147+
148+
func (this *DinnerPlates) PopAtStack(index int) int {
149+
if index < 0 || index >= len(*this.leftIndies) {
150+
return -1
151+
}
152+
v := (*this.leftIndies)[index]
153+
l := len(v.stack)
154+
if l == 0 {
155+
return -1
156+
}
157+
x := v.stack[l-1]
158+
v.stack = v.stack[:l-1]
159+
heap.Fix(this.leftNotFull, v.index)
160+
heap.Fix(this.rightNotEmpty, this.rightIndies[v.sourceIndex].index)
161+
return x
162+
}
163+
164+
type opt struct {
165+
name string
166+
i int
167+
}
168+
169+
func Solution(capacity int, opts []opt) []int {
170+
c := Constructor(capacity)
171+
var ret []int
172+
for _, op := range opts {
173+
if op.name == "push" {
174+
c.Push(op.i)
175+
continue
176+
}
177+
if op.name == "popAtStack" {
178+
ret = append(ret, c.PopAtStack(op.i))
179+
continue
180+
}
181+
if op.name == "pop" {
182+
ret = append(ret, c.Pop())
183+
}
184+
}
185+
return ret
186+
}

leetcode/1101-1200/1172.Dinner-Plate-Stacks/Solution_test.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,45 @@ func TestSolution(t *testing.T) {
1010
// 测试用例
1111
cases := []struct {
1212
name string
13-
inputs bool
14-
expect bool
13+
inputs int
14+
opts []opt
15+
expect []int
1516
}{
16-
{"TestCase", true, true},
17-
{"TestCase", true, true},
18-
{"TestCase", false, false},
17+
{"TestCase1", 2, []opt{
18+
{"push", 1},
19+
{"push", 2},
20+
{"push", 3},
21+
{"push", 4},
22+
{"push", 5},
23+
{"popAtStack", 0},
24+
{"push", 20},
25+
{"push", 21},
26+
{"popAtStack", 0},
27+
{"popAtStack", 2},
28+
{"pop", 0},
29+
{"pop", 0},
30+
{"pop", 0},
31+
{"pop", 0},
32+
{"pop", 0},
33+
}, []int{2, 20, 21, 5, 4, 3, 1, -1}},
1934
}
2035

2136
// 开始测试
2237
for i, c := range cases {
2338
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
24-
got := Solution(c.inputs)
39+
got := Solution(c.inputs, c.opts)
2540
if !reflect.DeepEqual(got, c.expect) {
26-
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
27-
c.expect, got, c.inputs)
41+
t.Fatalf("expected: %v, but got: %v, with inputs: %v %v",
42+
c.expect, got, c.inputs, c.opts)
2843
}
2944
})
3045
}
3146
}
3247

33-
// 压力测试
48+
// 压力测试
3449
func BenchmarkSolution(b *testing.B) {
3550
}
3651

37-
// 使用案列
52+
// 使用案列
3853
func ExampleSolution() {
3954
}

0 commit comments

Comments
 (0)