Skip to content

Commit 024a09d

Browse files
authored
feat: add solutions to lcci problem: No.03.01 (#2531)
No.03.01.Three in One
1 parent 5a8ae3f commit 024a09d

File tree

7 files changed

+410
-134
lines changed

7 files changed

+410
-134
lines changed

lcci/03.01.Three in One/README.md

+143-45
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,47 @@
3232

3333
## 解法
3434

35-
### 方法一
35+
### 方法一:数组模拟
36+
37+
我们使用一个变量 $cap$ 来表示每个栈的大小,使用一个长度为 $3 \times \text{cap} + 3$ 的数组 $stk$ 来模拟三个栈,数组的前 $3 \times \text{cap}$ 个元素用来存储栈的元素,数组的后三个元素用来存储每个栈的元素个数。
38+
39+
对于 `push` 操作,我们首先判断栈是否已满,如果未满,则将元素压入栈中,并更新栈的元素个数。
40+
41+
对于 `pop` 操作,我们首先判断栈是否为空,如果不为空,则更新栈的元素个数,并返回栈顶元素。
42+
43+
对于 `peek` 操作,我们首先判断栈是否为空,如果不为空,则返回栈顶元素。
44+
45+
对于 `isEmpty` 操作,我们直接判断栈是否为空即可。对于栈 $i$,我们只需要判断 $stk[\text{cap} \times 3 + i]$ 是否为 $0$ 即可。
46+
47+
时间复杂度上,每个操作的时间复杂度均为 $O(1)$。空间复杂度为 $O(\text{cap})$,其中 $\text{cap}$ 为栈的大小。
3648

3749
<!-- tabs:start -->
3850

3951
```python
4052
class TripleInOne:
53+
4154
def __init__(self, stackSize: int):
42-
self._capacity = stackSize
43-
self._s = [[], [], []]
55+
self.cap = stackSize
56+
self.stk = [0] * (self.cap * 3 + 3)
4457

4558
def push(self, stackNum: int, value: int) -> None:
46-
if len(self._s[stackNum]) < self._capacity:
47-
self._s[stackNum].append(value)
59+
if self.stk[self.cap * 3 + stackNum] < self.cap:
60+
self.stk[self.cap * stackNum + self.stk[self.cap * 3 + stackNum]] = value
61+
self.stk[self.cap * 3 + stackNum] += 1
4862

4963
def pop(self, stackNum: int) -> int:
50-
return -1 if self.isEmpty(stackNum) else self._s[stackNum].pop()
64+
if self.isEmpty(stackNum):
65+
return -1
66+
self.stk[self.cap * 3 + stackNum] -= 1
67+
return self.stk[self.cap * stackNum + self.stk[self.cap * 3 + stackNum]]
5168

5269
def peek(self, stackNum: int) -> int:
53-
return -1 if self.isEmpty(stackNum) else self._s[stackNum][-1]
70+
if self.isEmpty(stackNum):
71+
return -1
72+
return self.stk[self.cap * stackNum + self.stk[self.cap * 3 + stackNum] - 1]
5473

5574
def isEmpty(self, stackNum: int) -> bool:
56-
return len(self._s[stackNum]) == 0
75+
return self.stk[self.cap * 3 + stackNum] == 0
5776

5877

5978
# Your TripleInOne object will be instantiated and called as such:
@@ -66,35 +85,35 @@ class TripleInOne:
6685

6786
```java
6887
class TripleInOne {
69-
private int[] s;
70-
private int capacity;
88+
private int cap;
89+
private int[] stk;
7190

7291
public TripleInOne(int stackSize) {
73-
s = new int[stackSize * 3 + 3];
74-
capacity = stackSize;
92+
cap = stackSize;
93+
stk = new int[cap * 3 + 3];
7594
}
7695

7796
public void push(int stackNum, int value) {
78-
if (s[stackNum + 3 * capacity] < capacity) {
79-
s[s[stackNum + 3 * capacity] * 3 + stackNum] = value;
80-
++s[stackNum + 3 * capacity];
97+
if (stk[cap * 3 + stackNum] < cap) {
98+
stk[cap * stackNum + stk[cap * 3 + stackNum]] = value;
99+
++stk[cap * 3 + stackNum];
81100
}
82101
}
83102

84103
public int pop(int stackNum) {
85104
if (isEmpty(stackNum)) {
86105
return -1;
87106
}
88-
--s[stackNum + 3 * capacity];
89-
return s[s[stackNum + 3 * capacity] * 3 + stackNum];
107+
--stk[cap * 3 + stackNum];
108+
return stk[cap * stackNum + stk[cap * 3 + stackNum]];
90109
}
91110

92111
public int peek(int stackNum) {
93-
return isEmpty(stackNum) ? -1 : s[(s[stackNum + 3 * capacity] - 1) * 3 + stackNum];
112+
return isEmpty(stackNum) ? -1 : stk[cap * stackNum + stk[cap * 3 + stackNum] - 1];
94113
}
95114

96115
public boolean isEmpty(int stackNum) {
97-
return s[stackNum + 3 * capacity] == 0;
116+
return stk[cap * 3 + stackNum] == 0;
98117
}
99118
}
100119

@@ -108,54 +127,86 @@ class TripleInOne {
108127
*/
109128
```
110129

130+
```cpp
131+
class TripleInOne {
132+
public:
133+
TripleInOne(int stackSize) {
134+
cap = stackSize;
135+
stk.resize(cap * 3 + 3);
136+
}
137+
138+
void push(int stackNum, int value) {
139+
if (stk[cap * 3 + stackNum] < cap) {
140+
stk[cap * stackNum + stk[cap * 3 + stackNum]] = value;
141+
++stk[cap * 3 + stackNum];
142+
}
143+
}
144+
145+
int pop(int stackNum) {
146+
if (isEmpty(stackNum)) {
147+
return -1;
148+
}
149+
--stk[cap * 3 + stackNum];
150+
return stk[cap * stackNum + stk[cap * 3 + stackNum]];
151+
}
152+
153+
int peek(int stackNum) {
154+
return isEmpty(stackNum) ? -1 : stk[cap * stackNum + stk[cap * 3 + stackNum] - 1];
155+
}
156+
157+
bool isEmpty(int stackNum) {
158+
return stk[cap * 3 + stackNum] == 0;
159+
}
160+
161+
private:
162+
int cap;
163+
vector<int> stk;
164+
};
165+
166+
/**
167+
* Your TripleInOne object will be instantiated and called as such:
168+
* TripleInOne* obj = new TripleInOne(stackSize);
169+
* obj->push(stackNum,value);
170+
* int param_2 = obj->pop(stackNum);
171+
* int param_3 = obj->peek(stackNum);
172+
* bool param_4 = obj->isEmpty(stackNum);
173+
*/
174+
```
175+
111176
```go
112177
type TripleInOne struct {
113-
data []int
114-
offset [3]int
115-
stackSize int
178+
cap int
179+
stk []int
116180
}
117181
118182
func Constructor(stackSize int) TripleInOne {
119-
total := stackSize * 3
120-
data := make([]int, total)
121-
offset := [3]int{}
122-
for i := 0; i < 3; i++ {
123-
offset[i] = i * stackSize
124-
}
125-
return TripleInOne{
126-
data: data,
127-
offset: offset,
128-
stackSize: stackSize,
129-
}
183+
return TripleInOne{stackSize, make([]int, stackSize*3+3)}
130184
}
131185
132186
func (this *TripleInOne) Push(stackNum int, value int) {
133-
i := this.offset[stackNum]
134-
if i < (stackNum+1)*this.stackSize {
135-
this.data[i] = value
136-
this.offset[stackNum]++
187+
if this.stk[this.cap*3+stackNum] < this.cap {
188+
this.stk[this.cap*stackNum+this.stk[this.cap*3+stackNum]] = value
189+
this.stk[this.cap*3+stackNum]++
137190
}
138191
}
139192
140193
func (this *TripleInOne) Pop(stackNum int) int {
141-
i := this.offset[stackNum]
142-
if i == stackNum*this.stackSize {
194+
if this.IsEmpty(stackNum) {
143195
return -1
144196
}
145-
this.offset[stackNum]--
146-
return this.data[i-1]
197+
this.stk[this.cap*3+stackNum]--
198+
return this.stk[this.cap*stackNum+this.stk[this.cap*3+stackNum]]
147199
}
148200
149201
func (this *TripleInOne) Peek(stackNum int) int {
150-
i := this.offset[stackNum]
151-
if i == stackNum*this.stackSize {
202+
if this.IsEmpty(stackNum) {
152203
return -1
153204
}
154-
return this.data[i-1]
205+
return this.stk[this.cap*stackNum+this.stk[this.cap*3+stackNum]-1]
155206
}
156207
157208
func (this *TripleInOne) IsEmpty(stackNum int) bool {
158-
return this.offset[stackNum] == stackNum*this.stackSize
209+
return this.stk[this.cap*3+stackNum] == 0
159210
}
160211
161212
/**
@@ -168,6 +219,53 @@ func (this *TripleInOne) IsEmpty(stackNum int) bool {
168219
*/
169220
```
170221

222+
```ts
223+
class TripleInOne {
224+
private cap: number;
225+
private stk: number[];
226+
227+
constructor(stackSize: number) {
228+
this.cap = stackSize;
229+
this.stk = Array<number>(stackSize * 3 + 3).fill(0);
230+
}
231+
232+
push(stackNum: number, value: number): void {
233+
if (this.stk[this.cap * 3 + stackNum] < this.cap) {
234+
this.stk[this.cap * stackNum + this.stk[this.cap * 3 + stackNum]] = value;
235+
this.stk[this.cap * 3 + stackNum]++;
236+
}
237+
}
238+
239+
pop(stackNum: number): number {
240+
if (this.isEmpty(stackNum)) {
241+
return -1;
242+
}
243+
this.stk[this.cap * 3 + stackNum]--;
244+
return this.stk[this.cap * stackNum + this.stk[this.cap * 3 + stackNum]];
245+
}
246+
247+
peek(stackNum: number): number {
248+
if (this.isEmpty(stackNum)) {
249+
return -1;
250+
}
251+
return this.stk[this.cap * stackNum + this.stk[this.cap * 3 + stackNum] - 1];
252+
}
253+
254+
isEmpty(stackNum: number): boolean {
255+
return this.stk[this.cap * 3 + stackNum] === 0;
256+
}
257+
}
258+
259+
/**
260+
* Your TripleInOne object will be instantiated and called as such:
261+
* var obj = new TripleInOne(stackSize)
262+
* obj.push(stackNum,value)
263+
* var param_2 = obj.pop(stackNum)
264+
* var param_3 = obj.peek(stackNum)
265+
* var param_4 = obj.isEmpty(stackNum)
266+
*/
267+
```
268+
171269
<!-- tabs:end -->
172270

173271
<!-- end -->

0 commit comments

Comments
 (0)