diff --git a/lcci/03.05.Sort of Stacks/README.md b/lcci/03.05.Sort of Stacks/README.md index 7237b9d2c44ad..61300673577e0 100644 --- a/lcci/03.05.Sort of Stacks/README.md +++ b/lcci/03.05.Sort of Stacks/README.md @@ -33,64 +33,85 @@ ## 解法 -### 方法一 +### 方法一:栈 + 辅助栈 + +我们定义一个栈 $stk$,用于存放元素。 + +在 `push` 操作中,我们定义一个辅助栈 $t$,用于存放 $stk$ 中比当前元素小的元素。我们将 $stk$ 中比当前元素小的元素全部弹出并存放到 $t$ 中,然后将当前元素压入 $stk$,最后将 $t$ 中的元素全部弹出并压入 $stk$。时间复杂度 $O(n)$。 + +在 `pop` 操作中,我们只需要判断 $stk$ 是否为空,如果不为空,则弹出栈顶元素。时间复杂度 $O(1)$。 + +在 `peek` 操作中,我们只需要判断 $stk$ 是否为空,如果为空则返回 -1,否则返回栈顶元素。时间复杂度 $O(1)$。 + +在 `isEmpty` 操作中,我们只需要判断 $stk$ 是否为空。时间复杂度 $O(1)$。 + +空间复杂度 $O(n)$,其中 $n$ 为栈中元素的个数。 ```python class SortedStack: + def __init__(self): - self.s = [] + self.stk = [] def push(self, val: int) -> None: t = [] - while not self.isEmpty() and self.s[-1] < val: - t.append(self.s.pop()) - self.s.append(val) - while len(t) > 0: - self.s.append(t.pop()) + while self.stk and self.stk[-1] < val: + t.append(self.stk.pop()) + self.stk.append(val) + while t: + self.stk.append(t.pop()) def pop(self) -> None: if not self.isEmpty(): - self.s.pop() + self.stk.pop() def peek(self) -> int: - return -1 if self.isEmpty() else self.s[-1] + return -1 if self.isEmpty() else self.stk[-1] def isEmpty(self) -> bool: - return len(self.s) == 0 + return not self.stk + + +# Your SortedStack object will be instantiated and called as such: +# obj = SortedStack() +# obj.push(val) +# obj.pop() +# param_3 = obj.peek() +# param_4 = obj.isEmpty() ``` ```java class SortedStack { - private Stack s; + private Deque stk = new ArrayDeque<>(); + public SortedStack() { - s = new Stack<>(); } public void push(int val) { - Stack t = new Stack<>(); - while (!isEmpty() && s.peek() < val) { - t.push(s.pop()); + Deque t = new ArrayDeque<>(); + while (!stk.isEmpty() && stk.peek() < val) { + t.push(stk.pop()); } - s.push(val); + stk.push(val); while (!t.isEmpty()) { - s.push(t.pop()); + stk.push(t.pop()); } } public void pop() { if (!isEmpty()) { - s.pop(); + stk.pop(); } } public int peek() { - return isEmpty() ? -1 : s.peek(); + return isEmpty() ? -1 : stk.peek(); } public boolean isEmpty() { - return s.isEmpty(); + return stk.isEmpty(); } } @@ -104,74 +125,129 @@ class SortedStack { */ ``` +```cpp +class SortedStack { +public: + SortedStack() { + } + + void push(int val) { + stack t; + while (!stk.empty() && stk.top() < val) { + t.push(stk.top()); + stk.pop(); + } + stk.push(val); + while (!t.empty()) { + stk.push(t.top()); + t.pop(); + } + } + + void pop() { + if (!isEmpty()) { + stk.pop(); + } + } + + int peek() { + return isEmpty() ? -1 : stk.top(); + } + + bool isEmpty() { + return stk.empty(); + } + +private: + stack stk; +}; + +/** + * Your SortedStack object will be instantiated and called as such: + * SortedStack* obj = new SortedStack(); + * obj->push(val); + * obj->pop(); + * int param_3 = obj->peek(); + * bool param_4 = obj->isEmpty(); + */ +``` + ```go type SortedStack struct { - data []int + stk []int } func Constructor() SortedStack { - return SortedStack{make([]int, 0)} + return SortedStack{} } -func (s *SortedStack) Push(val int) { - temp := make([]int, 0) - for !s.IsEmpty() && s.Peek() < val { - temp = append(temp, s.Peek()) - s.Pop() +func (this *SortedStack) Push(val int) { + t := make([]int, 0) + for len(this.stk) > 0 && this.stk[len(this.stk)-1] < val { + t = append(t, this.stk[len(this.stk)-1]) + this.stk = this.stk[:len(this.stk)-1] } - s.data = append(s.data, val) - for len(temp) > 0 { - s.data = append(s.data, temp[len(temp)-1]) - temp = temp[:len(temp)-1] + this.stk = append(this.stk, val) + for i := len(t) - 1; i >= 0; i-- { + this.stk = append(this.stk, t[i]) } } -func (s *SortedStack) Pop() { - if !s.IsEmpty() { - s.data = s.data[:len(s.data)-1] +func (this *SortedStack) Pop() { + if !this.IsEmpty() { + this.stk = this.stk[:len(this.stk)-1] } } -func (s *SortedStack) Peek() int { - if !s.IsEmpty() { - return s.data[len(s.data)-1] +func (this *SortedStack) Peek() int { + if this.IsEmpty() { + return -1 } - return -1 + return this.stk[len(this.stk)-1] } -func (s *SortedStack) IsEmpty() bool { - return len(s.data) == 0 +func (this *SortedStack) IsEmpty() bool { + return len(this.stk) == 0 } + +/** + * Your SortedStack object will be instantiated and called as such: + * obj := Constructor(); + * obj.Push(val); + * obj.Pop(); + * param_3 := obj.Peek(); + * param_4 := obj.IsEmpty(); + */ ``` ```ts class SortedStack { - stack: number[]; - constructor() { - this.stack = []; - } + private stk: number[] = []; + constructor() {} push(val: number): void { - let t = []; - while (!this.isEmpty() && this.peek() < val) { - t.push(this.stack.pop()); + const t: number[] = []; + while (this.stk.length > 0 && this.stk.at(-1)! < val) { + t.push(this.stk.pop()!); } - this.stack.push(val); + this.stk.push(val); while (t.length > 0) { - this.stack.push(t.pop()); + this.stk.push(t.pop()!); } } pop(): void { - this.stack.pop(); + if (!this.isEmpty()) { + this.stk.pop(); + } } peek(): number { - return this.isEmpty() ? -1 : this.stack[this.stack.length - 1]; + return this.isEmpty() ? -1 : this.stk.at(-1)!; } isEmpty(): boolean { - return this.stack.length == 0; + return this.stk.length === 0; } } @@ -187,39 +263,46 @@ class SortedStack { ```rust use std::collections::VecDeque; + struct SortedStack { - stack: VecDeque, + stk: VecDeque, } -/** - * `&self` means the method takes an immutable reference. - * If you need a mutable reference, change it to `&mut self` instead. - */ impl SortedStack { fn new() -> Self { - Self { stack: VecDeque::new() } + SortedStack { + stk: VecDeque::new(), + } } fn push(&mut self, val: i32) { - if self.is_empty() || self.peek() > val { - self.stack.push_back(val); - return; + let mut t = VecDeque::new(); + while let Some(top) = self.stk.pop_back() { + if top < val { + t.push_back(top); + } else { + self.stk.push_back(top); + break; + } + } + self.stk.push_back(val); + while let Some(top) = t.pop_back() { + self.stk.push_back(top); } - let t = self.stack.pop_back().unwrap(); - self.push(val); - self.stack.push_back(t); } fn pop(&mut self) { - self.stack.pop_back(); + if !self.is_empty() { + self.stk.pop_back(); + } } fn peek(&self) -> i32 { - *self.stack.back().unwrap_or(&-1) + if self.is_empty() { -1 } else { *self.stk.back().unwrap() } } fn is_empty(&self) -> bool { - self.stack.is_empty() + self.stk.is_empty() } }/** * Your SortedStack object will be instantiated and called as such: @@ -233,52 +316,4 @@ impl SortedStack { -### 方法二 - - - -```ts -class SortedStack { - private stack: number[]; - - constructor() { - this.stack = []; - } - - push(val: number): void { - if (this.isEmpty() || this.peek() > val) { - this.stack.push(val); - return; - } - - const tmp = this.stack.pop(); - this.push(val); - this.stack.push(tmp); - } - - pop(): void { - this.stack.pop(); - } - - peek(): number { - return this.stack[this.stack.length - 1] ?? -1; - } - - isEmpty(): boolean { - return this.stack.length === 0; - } -} - -/** - * Your SortedStack object will be instantiated and called as such: - * var obj = new SortedStack() - * obj.push(val) - * obj.pop() - * var param_3 = obj.peek() - * var param_4 = obj.isEmpty() - */ -``` - - - diff --git a/lcci/03.05.Sort of Stacks/README_EN.md b/lcci/03.05.Sort of Stacks/README_EN.md index 067fe202e020d..6d271098371ad 100644 --- a/lcci/03.05.Sort of Stacks/README_EN.md +++ b/lcci/03.05.Sort of Stacks/README_EN.md @@ -46,64 +46,85 @@ ## Solutions -### Solution 1 +### Solution 1: Stack + Auxiliary Stack + +We define a stack $stk$ for storing elements. + +In the `push` operation, we define an auxiliary stack $t$ for storing elements in $stk$ that are smaller than the current element. We pop all elements smaller than the current element from $stk$ and store them in $t$, then push the current element into $stk$, and finally pop all elements from $t$ and push them back into $stk$. The time complexity is $O(n)$. + +In the `pop` operation, we just need to check if $stk$ is empty. If it's not, we pop the top element. The time complexity is $O(1)$. + +In the `peek` operation, we just need to check if $stk$ is empty. If it is, we return -1, otherwise, we return the top element. The time complexity is $O(1)$. + +In the `isEmpty` operation, we just need to check if $stk$ is empty. The time complexity is $O(1)$. + +The space complexity is $O(n)$, where $n$ is the number of elements in the stack. ```python class SortedStack: + def __init__(self): - self.s = [] + self.stk = [] def push(self, val: int) -> None: t = [] - while not self.isEmpty() and self.s[-1] < val: - t.append(self.s.pop()) - self.s.append(val) - while len(t) > 0: - self.s.append(t.pop()) + while self.stk and self.stk[-1] < val: + t.append(self.stk.pop()) + self.stk.append(val) + while t: + self.stk.append(t.pop()) def pop(self) -> None: if not self.isEmpty(): - self.s.pop() + self.stk.pop() def peek(self) -> int: - return -1 if self.isEmpty() else self.s[-1] + return -1 if self.isEmpty() else self.stk[-1] def isEmpty(self) -> bool: - return len(self.s) == 0 + return not self.stk + + +# Your SortedStack object will be instantiated and called as such: +# obj = SortedStack() +# obj.push(val) +# obj.pop() +# param_3 = obj.peek() +# param_4 = obj.isEmpty() ``` ```java class SortedStack { - private Stack s; + private Deque stk = new ArrayDeque<>(); + public SortedStack() { - s = new Stack<>(); } public void push(int val) { - Stack t = new Stack<>(); - while (!isEmpty() && s.peek() < val) { - t.push(s.pop()); + Deque t = new ArrayDeque<>(); + while (!stk.isEmpty() && stk.peek() < val) { + t.push(stk.pop()); } - s.push(val); + stk.push(val); while (!t.isEmpty()) { - s.push(t.pop()); + stk.push(t.pop()); } } public void pop() { if (!isEmpty()) { - s.pop(); + stk.pop(); } } public int peek() { - return isEmpty() ? -1 : s.peek(); + return isEmpty() ? -1 : stk.peek(); } public boolean isEmpty() { - return s.isEmpty(); + return stk.isEmpty(); } } @@ -117,74 +138,129 @@ class SortedStack { */ ``` +```cpp +class SortedStack { +public: + SortedStack() { + } + + void push(int val) { + stack t; + while (!stk.empty() && stk.top() < val) { + t.push(stk.top()); + stk.pop(); + } + stk.push(val); + while (!t.empty()) { + stk.push(t.top()); + t.pop(); + } + } + + void pop() { + if (!isEmpty()) { + stk.pop(); + } + } + + int peek() { + return isEmpty() ? -1 : stk.top(); + } + + bool isEmpty() { + return stk.empty(); + } + +private: + stack stk; +}; + +/** + * Your SortedStack object will be instantiated and called as such: + * SortedStack* obj = new SortedStack(); + * obj->push(val); + * obj->pop(); + * int param_3 = obj->peek(); + * bool param_4 = obj->isEmpty(); + */ +``` + ```go type SortedStack struct { - data []int + stk []int } func Constructor() SortedStack { - return SortedStack{make([]int, 0)} + return SortedStack{} } -func (s *SortedStack) Push(val int) { - temp := make([]int, 0) - for !s.IsEmpty() && s.Peek() < val { - temp = append(temp, s.Peek()) - s.Pop() +func (this *SortedStack) Push(val int) { + t := make([]int, 0) + for len(this.stk) > 0 && this.stk[len(this.stk)-1] < val { + t = append(t, this.stk[len(this.stk)-1]) + this.stk = this.stk[:len(this.stk)-1] } - s.data = append(s.data, val) - for len(temp) > 0 { - s.data = append(s.data, temp[len(temp)-1]) - temp = temp[:len(temp)-1] + this.stk = append(this.stk, val) + for i := len(t) - 1; i >= 0; i-- { + this.stk = append(this.stk, t[i]) } } -func (s *SortedStack) Pop() { - if !s.IsEmpty() { - s.data = s.data[:len(s.data)-1] +func (this *SortedStack) Pop() { + if !this.IsEmpty() { + this.stk = this.stk[:len(this.stk)-1] } } -func (s *SortedStack) Peek() int { - if !s.IsEmpty() { - return s.data[len(s.data)-1] +func (this *SortedStack) Peek() int { + if this.IsEmpty() { + return -1 } - return -1 + return this.stk[len(this.stk)-1] } -func (s *SortedStack) IsEmpty() bool { - return len(s.data) == 0 +func (this *SortedStack) IsEmpty() bool { + return len(this.stk) == 0 } + +/** + * Your SortedStack object will be instantiated and called as such: + * obj := Constructor(); + * obj.Push(val); + * obj.Pop(); + * param_3 := obj.Peek(); + * param_4 := obj.IsEmpty(); + */ ``` ```ts class SortedStack { - stack: number[]; - constructor() { - this.stack = []; - } + private stk: number[] = []; + constructor() {} push(val: number): void { - let t = []; - while (!this.isEmpty() && this.peek() < val) { - t.push(this.stack.pop()); + const t: number[] = []; + while (this.stk.length > 0 && this.stk.at(-1)! < val) { + t.push(this.stk.pop()!); } - this.stack.push(val); + this.stk.push(val); while (t.length > 0) { - this.stack.push(t.pop()); + this.stk.push(t.pop()!); } } pop(): void { - this.stack.pop(); + if (!this.isEmpty()) { + this.stk.pop(); + } } peek(): number { - return this.isEmpty() ? -1 : this.stack[this.stack.length - 1]; + return this.isEmpty() ? -1 : this.stk.at(-1)!; } isEmpty(): boolean { - return this.stack.length == 0; + return this.stk.length === 0; } } @@ -200,39 +276,46 @@ class SortedStack { ```rust use std::collections::VecDeque; + struct SortedStack { - stack: VecDeque, + stk: VecDeque, } -/** - * `&self` means the method takes an immutable reference. - * If you need a mutable reference, change it to `&mut self` instead. - */ impl SortedStack { fn new() -> Self { - Self { stack: VecDeque::new() } + SortedStack { + stk: VecDeque::new(), + } } fn push(&mut self, val: i32) { - if self.is_empty() || self.peek() > val { - self.stack.push_back(val); - return; + let mut t = VecDeque::new(); + while let Some(top) = self.stk.pop_back() { + if top < val { + t.push_back(top); + } else { + self.stk.push_back(top); + break; + } + } + self.stk.push_back(val); + while let Some(top) = t.pop_back() { + self.stk.push_back(top); } - let t = self.stack.pop_back().unwrap(); - self.push(val); - self.stack.push_back(t); } fn pop(&mut self) { - self.stack.pop_back(); + if !self.is_empty() { + self.stk.pop_back(); + } } fn peek(&self) -> i32 { - *self.stack.back().unwrap_or(&-1) + if self.is_empty() { -1 } else { *self.stk.back().unwrap() } } fn is_empty(&self) -> bool { - self.stack.is_empty() + self.stk.is_empty() } }/** * Your SortedStack object will be instantiated and called as such: @@ -246,52 +329,4 @@ impl SortedStack { -### Solution 2 - - - -```ts -class SortedStack { - private stack: number[]; - - constructor() { - this.stack = []; - } - - push(val: number): void { - if (this.isEmpty() || this.peek() > val) { - this.stack.push(val); - return; - } - - const tmp = this.stack.pop(); - this.push(val); - this.stack.push(tmp); - } - - pop(): void { - this.stack.pop(); - } - - peek(): number { - return this.stack[this.stack.length - 1] ?? -1; - } - - isEmpty(): boolean { - return this.stack.length === 0; - } -} - -/** - * Your SortedStack object will be instantiated and called as such: - * var obj = new SortedStack() - * obj.push(val) - * obj.pop() - * var param_3 = obj.peek() - * var param_4 = obj.isEmpty() - */ -``` - - - diff --git a/lcci/03.05.Sort of Stacks/Solution.cpp b/lcci/03.05.Sort of Stacks/Solution.cpp new file mode 100644 index 0000000000000..11aafbb6b2b8b --- /dev/null +++ b/lcci/03.05.Sort of Stacks/Solution.cpp @@ -0,0 +1,44 @@ +class SortedStack { +public: + SortedStack() { + } + + void push(int val) { + stack t; + while (!stk.empty() && stk.top() < val) { + t.push(stk.top()); + stk.pop(); + } + stk.push(val); + while (!t.empty()) { + stk.push(t.top()); + t.pop(); + } + } + + void pop() { + if (!isEmpty()) { + stk.pop(); + } + } + + int peek() { + return isEmpty() ? -1 : stk.top(); + } + + bool isEmpty() { + return stk.empty(); + } + +private: + stack stk; +}; + +/** + * Your SortedStack object will be instantiated and called as such: + * SortedStack* obj = new SortedStack(); + * obj->push(val); + * obj->pop(); + * int param_3 = obj->peek(); + * bool param_4 = obj->isEmpty(); + */ \ No newline at end of file diff --git a/lcci/03.05.Sort of Stacks/Solution.go b/lcci/03.05.Sort of Stacks/Solution.go index 65f623a6147ab..ad0757b4103e3 100644 --- a/lcci/03.05.Sort of Stacks/Solution.go +++ b/lcci/03.05.Sort of Stacks/Solution.go @@ -1,37 +1,45 @@ type SortedStack struct { - data []int + stk []int } func Constructor() SortedStack { - return SortedStack{make([]int, 0)} + return SortedStack{} } -func (s *SortedStack) Push(val int) { - temp := make([]int, 0) - for !s.IsEmpty() && s.Peek() < val { - temp = append(temp, s.Peek()) - s.Pop() +func (this *SortedStack) Push(val int) { + t := make([]int, 0) + for len(this.stk) > 0 && this.stk[len(this.stk)-1] < val { + t = append(t, this.stk[len(this.stk)-1]) + this.stk = this.stk[:len(this.stk)-1] } - s.data = append(s.data, val) - for len(temp) > 0 { - s.data = append(s.data, temp[len(temp)-1]) - temp = temp[:len(temp)-1] + this.stk = append(this.stk, val) + for i := len(t) - 1; i >= 0; i-- { + this.stk = append(this.stk, t[i]) } } -func (s *SortedStack) Pop() { - if !s.IsEmpty() { - s.data = s.data[:len(s.data)-1] +func (this *SortedStack) Pop() { + if !this.IsEmpty() { + this.stk = this.stk[:len(this.stk)-1] } } -func (s *SortedStack) Peek() int { - if !s.IsEmpty() { - return s.data[len(s.data)-1] +func (this *SortedStack) Peek() int { + if this.IsEmpty() { + return -1 } - return -1 + return this.stk[len(this.stk)-1] } -func (s *SortedStack) IsEmpty() bool { - return len(s.data) == 0 -} \ No newline at end of file +func (this *SortedStack) IsEmpty() bool { + return len(this.stk) == 0 +} + +/** + * Your SortedStack object will be instantiated and called as such: + * obj := Constructor(); + * obj.Push(val); + * obj.Pop(); + * param_3 := obj.Peek(); + * param_4 := obj.IsEmpty(); + */ \ No newline at end of file diff --git a/lcci/03.05.Sort of Stacks/Solution.java b/lcci/03.05.Sort of Stacks/Solution.java index 240a92d76010f..1ee1e3c31792f 100644 --- a/lcci/03.05.Sort of Stacks/Solution.java +++ b/lcci/03.05.Sort of Stacks/Solution.java @@ -1,32 +1,32 @@ class SortedStack { - private Stack s; + private Deque stk = new ArrayDeque<>(); + public SortedStack() { - s = new Stack<>(); } public void push(int val) { - Stack t = new Stack<>(); - while (!isEmpty() && s.peek() < val) { - t.push(s.pop()); + Deque t = new ArrayDeque<>(); + while (!stk.isEmpty() && stk.peek() < val) { + t.push(stk.pop()); } - s.push(val); + stk.push(val); while (!t.isEmpty()) { - s.push(t.pop()); + stk.push(t.pop()); } } public void pop() { if (!isEmpty()) { - s.pop(); + stk.pop(); } } public int peek() { - return isEmpty() ? -1 : s.peek(); + return isEmpty() ? -1 : stk.peek(); } public boolean isEmpty() { - return s.isEmpty(); + return stk.isEmpty(); } } diff --git a/lcci/03.05.Sort of Stacks/Solution.py b/lcci/03.05.Sort of Stacks/Solution.py index 48787e320bce7..4183429856a67 100644 --- a/lcci/03.05.Sort of Stacks/Solution.py +++ b/lcci/03.05.Sort of Stacks/Solution.py @@ -1,21 +1,30 @@ class SortedStack: + def __init__(self): - self.s = [] + self.stk = [] def push(self, val: int) -> None: t = [] - while not self.isEmpty() and self.s[-1] < val: - t.append(self.s.pop()) - self.s.append(val) - while len(t) > 0: - self.s.append(t.pop()) + while self.stk and self.stk[-1] < val: + t.append(self.stk.pop()) + self.stk.append(val) + while t: + self.stk.append(t.pop()) def pop(self) -> None: if not self.isEmpty(): - self.s.pop() + self.stk.pop() def peek(self) -> int: - return -1 if self.isEmpty() else self.s[-1] + return -1 if self.isEmpty() else self.stk[-1] def isEmpty(self) -> bool: - return len(self.s) == 0 + return not self.stk + + +# Your SortedStack object will be instantiated and called as such: +# obj = SortedStack() +# obj.push(val) +# obj.pop() +# param_3 = obj.peek() +# param_4 = obj.isEmpty() diff --git a/lcci/03.05.Sort of Stacks/Solution.rs b/lcci/03.05.Sort of Stacks/Solution.rs index e3f9ae5bd62d5..67e714c103769 100644 --- a/lcci/03.05.Sort of Stacks/Solution.rs +++ b/lcci/03.05.Sort of Stacks/Solution.rs @@ -1,37 +1,44 @@ use std::collections::VecDeque; + struct SortedStack { - stack: VecDeque, + stk: VecDeque, } -/** - * `&self` means the method takes an immutable reference. - * If you need a mutable reference, change it to `&mut self` instead. - */ impl SortedStack { fn new() -> Self { - Self { stack: VecDeque::new() } + SortedStack { + stk: VecDeque::new(), + } } fn push(&mut self, val: i32) { - if self.is_empty() || self.peek() > val { - self.stack.push_back(val); - return; + let mut t = VecDeque::new(); + while let Some(top) = self.stk.pop_back() { + if top < val { + t.push_back(top); + } else { + self.stk.push_back(top); + break; + } + } + self.stk.push_back(val); + while let Some(top) = t.pop_back() { + self.stk.push_back(top); } - let t = self.stack.pop_back().unwrap(); - self.push(val); - self.stack.push_back(t); } fn pop(&mut self) { - self.stack.pop_back(); + if !self.is_empty() { + self.stk.pop_back(); + } } fn peek(&self) -> i32 { - *self.stack.back().unwrap_or(&-1) + if self.is_empty() { -1 } else { *self.stk.back().unwrap() } } fn is_empty(&self) -> bool { - self.stack.is_empty() + self.stk.is_empty() } }/** * Your SortedStack object will be instantiated and called as such: diff --git a/lcci/03.05.Sort of Stacks/Solution.ts b/lcci/03.05.Sort of Stacks/Solution.ts index dab81b0c74459..1ed0aec93d832 100644 --- a/lcci/03.05.Sort of Stacks/Solution.ts +++ b/lcci/03.05.Sort of Stacks/Solution.ts @@ -1,30 +1,30 @@ class SortedStack { - stack: number[]; - constructor() { - this.stack = []; - } + private stk: number[] = []; + constructor() {} push(val: number): void { - let t = []; - while (!this.isEmpty() && this.peek() < val) { - t.push(this.stack.pop()); + const t: number[] = []; + while (this.stk.length > 0 && this.stk.at(-1)! < val) { + t.push(this.stk.pop()!); } - this.stack.push(val); + this.stk.push(val); while (t.length > 0) { - this.stack.push(t.pop()); + this.stk.push(t.pop()!); } } pop(): void { - this.stack.pop(); + if (!this.isEmpty()) { + this.stk.pop(); + } } peek(): number { - return this.isEmpty() ? -1 : this.stack[this.stack.length - 1]; + return this.isEmpty() ? -1 : this.stk.at(-1)!; } isEmpty(): boolean { - return this.stack.length == 0; + return this.stk.length === 0; } } diff --git a/lcci/03.05.Sort of Stacks/Solution2.ts b/lcci/03.05.Sort of Stacks/Solution2.ts deleted file mode 100644 index 3ca6e4c9c0eb2..0000000000000 --- a/lcci/03.05.Sort of Stacks/Solution2.ts +++ /dev/null @@ -1,39 +0,0 @@ -class SortedStack { - private stack: number[]; - - constructor() { - this.stack = []; - } - - push(val: number): void { - if (this.isEmpty() || this.peek() > val) { - this.stack.push(val); - return; - } - - const tmp = this.stack.pop(); - this.push(val); - this.stack.push(tmp); - } - - pop(): void { - this.stack.pop(); - } - - peek(): number { - return this.stack[this.stack.length - 1] ?? -1; - } - - isEmpty(): boolean { - return this.stack.length === 0; - } -} - -/** - * Your SortedStack object will be instantiated and called as such: - * var obj = new SortedStack() - * obj.push(val) - * obj.pop() - * var param_3 = obj.peek() - * var param_4 = obj.isEmpty() - */ diff --git a/lcci/03.06.Animal Shelter/README.md b/lcci/03.06.Animal Shelter/README.md index a28d24ebe5d8a..e1574c778a09c 100644 --- a/lcci/03.06.Animal Shelter/README.md +++ b/lcci/03.06.Animal Shelter/README.md @@ -37,34 +37,42 @@ ## 解法 -### 方法一 +### 方法一:数组嵌套队列 + +我们定义一个长度为 $2$ 的数组 $q$,用于存放猫和狗的队列。 + +在 `enqueue` 操作中,假设动物编号为 $i$,动物种类为 $j$,我们将 $i$ 入队到 $q[j]$ 中。 + +在 `dequeueAny` 操作中,我们判断 $q[0]$ 是否为空,或者 $q[1]$ 不为空且 $q[1][0] < q[0][0]$,如果是,则调用 `dequeueDog`,否则调用 `dequeueCat`。 + +在 `dequeueDog` 操作中,如果 $q[1]$ 为空,则返回 $[-1, -1]$,否则返回 $[q[1].pop(), 1]$。 + +在 `dequeueCat` 操作中,如果 $q[0]$ 为空,则返回 $[-1, -1]$,否则返回 $[q[0].pop(), 0]$。 + +以上操作的时间复杂度均为 $O(1)$,空间复杂度为 $O(n)$,其中 $n$ 为动物收容所中动物的数量。 ```python class AnimalShelf: + def __init__(self): - self.cats = [] - self.dogs = [] + self.q = [deque(), deque()] def enqueue(self, animal: List[int]) -> None: - if animal[1] == 0: - self.cats.insert(0, animal[0]) - else: - self.dogs.insert(0, animal[0]) + i, j = animal + self.q[j].append(i) def dequeueAny(self) -> List[int]: - if len(self.dogs) == 0: - return self.dequeueCat() - if len(self.cats) == 0: + if not self.q[0] or (self.q[1] and self.q[1][0] < self.q[0][0]): return self.dequeueDog() - return self.dequeueDog() if self.dogs[-1] < self.cats[-1] else self.dequeueCat() + return self.dequeueCat() def dequeueDog(self) -> List[int]: - return [-1, -1] if len(self.dogs) == 0 else [self.dogs.pop(), 1] + return [-1, -1] if not self.q[1] else [self.q[1].popleft(), 1] def dequeueCat(self) -> List[int]: - return [-1, -1] if len(self.cats) == 0 else [self.cats.pop(), 0] + return [-1, -1] if not self.q[0] else [self.q[0].popleft(), 0] # Your AnimalShelf object will be instantiated and called as such: @@ -77,34 +85,29 @@ class AnimalShelf: ```java class AnimalShelf { - Queue cats; - Queue dogs; + private Deque[] q = new Deque[2]; + public AnimalShelf() { - cats = new LinkedList<>(); - dogs = new LinkedList<>(); + Arrays.setAll(q, k -> new ArrayDeque<>()); } public void enqueue(int[] animal) { - if (animal[1] == 0) { - cats.offer(animal[0]); - } else { - dogs.offer(animal[0]); - } + q[animal[1]].offer(animal[0]); } public int[] dequeueAny() { - return dogs.isEmpty() - ? dequeueCat() - : (cats.isEmpty() ? dequeueDog() - : (dogs.peek() < cats.peek() ? dequeueDog() : dequeueCat())); + if (q[0].isEmpty() || (!q[1].isEmpty() && q[1].peek() < q[0].peek())) { + return dequeueDog(); + } + return dequeueCat(); } public int[] dequeueDog() { - return dogs.isEmpty() ? new int[] {-1, -1} : new int[] {dogs.poll(), 1}; + return q[1].isEmpty() ? new int[] {-1, -1} : new int[] {q[1].poll(), 1}; } public int[] dequeueCat() { - return cats.isEmpty() ? new int[] {-1, -1} : new int[] {cats.poll(), 0}; + return q[0].isEmpty() ? new int[] {-1, -1} : new int[] {q[0].poll(), 0}; } } @@ -118,46 +121,132 @@ class AnimalShelf { */ ``` -```ts +```cpp class AnimalShelf { - private cats: number[]; - private dogs: number[]; +public: + AnimalShelf() { + } - constructor() { - this.cats = []; - this.dogs = []; + void enqueue(vector animal) { + q[animal[1]].push(animal[0]); } + vector dequeueAny() { + if (q[0].empty() || (!q[1].empty() && q[1].front() < q[0].front())) { + return dequeueDog(); + } + return dequeueCat(); + } + + vector dequeueDog() { + if (q[1].empty()) { + return {-1, -1}; + } + int dog = q[1].front(); + q[1].pop(); + return {dog, 1}; + } + + vector dequeueCat() { + if (q[0].empty()) { + return {-1, -1}; + } + int cat = q[0].front(); + q[0].pop(); + return {cat, 0}; + } + +private: + queue q[2]; +}; + +/** + * Your AnimalShelf object will be instantiated and called as such: + * AnimalShelf* obj = new AnimalShelf(); + * obj->enqueue(animal); + * vector param_2 = obj->dequeueAny(); + * vector param_3 = obj->dequeueDog(); + * vector param_4 = obj->dequeueCat(); + */ +``` + +```go +type AnimalShelf struct { + q [2][]int +} + +func Constructor() AnimalShelf { + return AnimalShelf{} +} + +func (this *AnimalShelf) Enqueue(animal []int) { + this.q[animal[1]] = append(this.q[animal[1]], animal[0]) +} + +func (this *AnimalShelf) DequeueAny() []int { + if len(this.q[0]) == 0 || (len(this.q[1]) > 0 && this.q[0][0] > this.q[1][0]) { + return this.DequeueDog() + } + return this.DequeueCat() +} + +func (this *AnimalShelf) DequeueDog() []int { + if len(this.q[1]) == 0 { + return []int{-1, -1} + } + dog := this.q[1][0] + this.q[1] = this.q[1][1:] + return []int{dog, 1} +} + +func (this *AnimalShelf) DequeueCat() []int { + if len(this.q[0]) == 0 { + return []int{-1, -1} + } + cat := this.q[0][0] + this.q[0] = this.q[0][1:] + return []int{cat, 0} +} + +/** + * Your AnimalShelf object will be instantiated and called as such: + * obj := Constructor(); + * obj.Enqueue(animal); + * param_2 := obj.DequeueAny(); + * param_3 := obj.DequeueDog(); + * param_4 := obj.DequeueCat(); + */ +``` + +```ts +class AnimalShelf { + private q: number[][] = [[], []]; + constructor() {} + enqueue(animal: number[]): void { const [i, j] = animal; - this[j === 0 ? 'cats' : 'dogs'].push(i); + this.q[j].push(i); } dequeueAny(): number[] { - const n = this.dogs.length; - const m = this.cats.length; - if (n === 0 && m === 0) { - return [-1, -1]; - } - if ((this.dogs[0] ?? Infinity) < (this.cats[0] ?? Infinity)) { - return [this.dogs.shift(), 1]; - } else { - return [this.cats.shift(), 0]; + if (this.q[0].length === 0 || (this.q[1].length > 0 && this.q[0][0] > this.q[1][0])) { + return this.dequeueDog(); } + return this.dequeueCat(); } dequeueDog(): number[] { - if (this.dogs.length === 0) { + if (this.q[1].length === 0) { return [-1, -1]; } - return [this.dogs.shift(), 1]; + return [this.q[1].shift()!, 1]; } dequeueCat(): number[] { - if (this.cats.length === 0) { + if (this.q[0].length === 0) { return [-1, -1]; } - return [this.cats.shift(), 0]; + return [this.q[0].shift()!, 0]; } } @@ -175,53 +264,47 @@ class AnimalShelf { use std::collections::VecDeque; struct AnimalShelf { - cats: VecDeque, - dogs: VecDeque, + q: [VecDeque; 2], } -/** - * `&self` means the method takes an immutable reference. - * If you need a mutable reference, change it to `&mut self` instead. - */ impl AnimalShelf { fn new() -> Self { - Self { - cats: VecDeque::new(), - dogs: VecDeque::new(), + AnimalShelf { + q: [VecDeque::new(), VecDeque::new()], } } fn enqueue(&mut self, animal: Vec) { - if animal[1] == 0 { - self.cats.push_back(animal[0]); - } else { - self.dogs.push_back(animal[0]); - } + self.q[animal[1] as usize].push_back(animal[0]); } fn dequeue_any(&mut self) -> Vec { - match (self.cats.is_empty(), self.dogs.is_empty()) { - (true, true) => vec![-1, -1], - (true, false) => self.dequeue_dog(), - (false, true) => self.dequeue_cat(), - (false, false) => { - if self.dogs[0] < self.cats[0] { self.dequeue_dog() } else { self.dequeue_cat() } - } + if + self.q[0].is_empty() || + (!self.q[1].is_empty() && self.q[1].front().unwrap() < self.q[0].front().unwrap()) + { + self.dequeue_dog() + } else { + self.dequeue_cat() } } fn dequeue_dog(&mut self) -> Vec { - if self.dogs.is_empty() { - return vec![-1, -1]; + if self.q[1].is_empty() { + vec![-1, -1] + } else { + let dog = self.q[1].pop_front().unwrap(); + vec![dog, 1] } - vec![self.dogs.pop_front().unwrap(), 1] } fn dequeue_cat(&mut self) -> Vec { - if self.cats.is_empty() { - return vec![-1, -1]; + if self.q[0].is_empty() { + vec![-1, -1] + } else { + let cat = self.q[0].pop_front().unwrap(); + vec![cat, 0] } - vec![self.cats.pop_front().unwrap(), 0] } }/** * Your AnimalShelf object will be instantiated and called as such: diff --git a/lcci/03.06.Animal Shelter/README_EN.md b/lcci/03.06.Animal Shelter/README_EN.md index 1c30d258238c7..0b53a6cff2100 100644 --- a/lcci/03.06.Animal Shelter/README_EN.md +++ b/lcci/03.06.Animal Shelter/README_EN.md @@ -50,34 +50,42 @@ ## Solutions -### Solution 1 +### Solution 1: Array of Queues + +We define an array $q$ of length $2$ to store the queues of cats and dogs. + +In the `enqueue` operation, assuming the animal number is $i$ and the animal type is $j$, we enqueue $i$ into $q[j]$. + +In the `dequeueAny` operation, we check whether $q[0]$ is empty, or $q[1]$ is not empty and $q[1][0] < q[0][0]$. If so, we call `dequeueDog`, otherwise we call `dequeueCat`. + +In the `dequeueDog` operation, if $q[1]$ is empty, we return $[-1, -1]$, otherwise we return $[q[1].pop(), 1]$. + +In the `dequeueCat` operation, if $q[0]$ is empty, we return $[-1, -1]$, otherwise we return $[q[0].pop(), 0]$. + +The time complexity of the above operations is $O(1)$, and the space complexity is $O(n)$, where $n$ is the number of animals in the animal shelter. ```python class AnimalShelf: + def __init__(self): - self.cats = [] - self.dogs = [] + self.q = [deque(), deque()] def enqueue(self, animal: List[int]) -> None: - if animal[1] == 0: - self.cats.insert(0, animal[0]) - else: - self.dogs.insert(0, animal[0]) + i, j = animal + self.q[j].append(i) def dequeueAny(self) -> List[int]: - if len(self.dogs) == 0: - return self.dequeueCat() - if len(self.cats) == 0: + if not self.q[0] or (self.q[1] and self.q[1][0] < self.q[0][0]): return self.dequeueDog() - return self.dequeueDog() if self.dogs[-1] < self.cats[-1] else self.dequeueCat() + return self.dequeueCat() def dequeueDog(self) -> List[int]: - return [-1, -1] if len(self.dogs) == 0 else [self.dogs.pop(), 1] + return [-1, -1] if not self.q[1] else [self.q[1].popleft(), 1] def dequeueCat(self) -> List[int]: - return [-1, -1] if len(self.cats) == 0 else [self.cats.pop(), 0] + return [-1, -1] if not self.q[0] else [self.q[0].popleft(), 0] # Your AnimalShelf object will be instantiated and called as such: @@ -90,34 +98,29 @@ class AnimalShelf: ```java class AnimalShelf { - Queue cats; - Queue dogs; + private Deque[] q = new Deque[2]; + public AnimalShelf() { - cats = new LinkedList<>(); - dogs = new LinkedList<>(); + Arrays.setAll(q, k -> new ArrayDeque<>()); } public void enqueue(int[] animal) { - if (animal[1] == 0) { - cats.offer(animal[0]); - } else { - dogs.offer(animal[0]); - } + q[animal[1]].offer(animal[0]); } public int[] dequeueAny() { - return dogs.isEmpty() - ? dequeueCat() - : (cats.isEmpty() ? dequeueDog() - : (dogs.peek() < cats.peek() ? dequeueDog() : dequeueCat())); + if (q[0].isEmpty() || (!q[1].isEmpty() && q[1].peek() < q[0].peek())) { + return dequeueDog(); + } + return dequeueCat(); } public int[] dequeueDog() { - return dogs.isEmpty() ? new int[] {-1, -1} : new int[] {dogs.poll(), 1}; + return q[1].isEmpty() ? new int[] {-1, -1} : new int[] {q[1].poll(), 1}; } public int[] dequeueCat() { - return cats.isEmpty() ? new int[] {-1, -1} : new int[] {cats.poll(), 0}; + return q[0].isEmpty() ? new int[] {-1, -1} : new int[] {q[0].poll(), 0}; } } @@ -131,46 +134,132 @@ class AnimalShelf { */ ``` -```ts +```cpp class AnimalShelf { - private cats: number[]; - private dogs: number[]; +public: + AnimalShelf() { + } - constructor() { - this.cats = []; - this.dogs = []; + void enqueue(vector animal) { + q[animal[1]].push(animal[0]); } + vector dequeueAny() { + if (q[0].empty() || (!q[1].empty() && q[1].front() < q[0].front())) { + return dequeueDog(); + } + return dequeueCat(); + } + + vector dequeueDog() { + if (q[1].empty()) { + return {-1, -1}; + } + int dog = q[1].front(); + q[1].pop(); + return {dog, 1}; + } + + vector dequeueCat() { + if (q[0].empty()) { + return {-1, -1}; + } + int cat = q[0].front(); + q[0].pop(); + return {cat, 0}; + } + +private: + queue q[2]; +}; + +/** + * Your AnimalShelf object will be instantiated and called as such: + * AnimalShelf* obj = new AnimalShelf(); + * obj->enqueue(animal); + * vector param_2 = obj->dequeueAny(); + * vector param_3 = obj->dequeueDog(); + * vector param_4 = obj->dequeueCat(); + */ +``` + +```go +type AnimalShelf struct { + q [2][]int +} + +func Constructor() AnimalShelf { + return AnimalShelf{} +} + +func (this *AnimalShelf) Enqueue(animal []int) { + this.q[animal[1]] = append(this.q[animal[1]], animal[0]) +} + +func (this *AnimalShelf) DequeueAny() []int { + if len(this.q[0]) == 0 || (len(this.q[1]) > 0 && this.q[0][0] > this.q[1][0]) { + return this.DequeueDog() + } + return this.DequeueCat() +} + +func (this *AnimalShelf) DequeueDog() []int { + if len(this.q[1]) == 0 { + return []int{-1, -1} + } + dog := this.q[1][0] + this.q[1] = this.q[1][1:] + return []int{dog, 1} +} + +func (this *AnimalShelf) DequeueCat() []int { + if len(this.q[0]) == 0 { + return []int{-1, -1} + } + cat := this.q[0][0] + this.q[0] = this.q[0][1:] + return []int{cat, 0} +} + +/** + * Your AnimalShelf object will be instantiated and called as such: + * obj := Constructor(); + * obj.Enqueue(animal); + * param_2 := obj.DequeueAny(); + * param_3 := obj.DequeueDog(); + * param_4 := obj.DequeueCat(); + */ +``` + +```ts +class AnimalShelf { + private q: number[][] = [[], []]; + constructor() {} + enqueue(animal: number[]): void { const [i, j] = animal; - this[j === 0 ? 'cats' : 'dogs'].push(i); + this.q[j].push(i); } dequeueAny(): number[] { - const n = this.dogs.length; - const m = this.cats.length; - if (n === 0 && m === 0) { - return [-1, -1]; - } - if ((this.dogs[0] ?? Infinity) < (this.cats[0] ?? Infinity)) { - return [this.dogs.shift(), 1]; - } else { - return [this.cats.shift(), 0]; + if (this.q[0].length === 0 || (this.q[1].length > 0 && this.q[0][0] > this.q[1][0])) { + return this.dequeueDog(); } + return this.dequeueCat(); } dequeueDog(): number[] { - if (this.dogs.length === 0) { + if (this.q[1].length === 0) { return [-1, -1]; } - return [this.dogs.shift(), 1]; + return [this.q[1].shift()!, 1]; } dequeueCat(): number[] { - if (this.cats.length === 0) { + if (this.q[0].length === 0) { return [-1, -1]; } - return [this.cats.shift(), 0]; + return [this.q[0].shift()!, 0]; } } @@ -188,53 +277,47 @@ class AnimalShelf { use std::collections::VecDeque; struct AnimalShelf { - cats: VecDeque, - dogs: VecDeque, + q: [VecDeque; 2], } -/** - * `&self` means the method takes an immutable reference. - * If you need a mutable reference, change it to `&mut self` instead. - */ impl AnimalShelf { fn new() -> Self { - Self { - cats: VecDeque::new(), - dogs: VecDeque::new(), + AnimalShelf { + q: [VecDeque::new(), VecDeque::new()], } } fn enqueue(&mut self, animal: Vec) { - if animal[1] == 0 { - self.cats.push_back(animal[0]); - } else { - self.dogs.push_back(animal[0]); - } + self.q[animal[1] as usize].push_back(animal[0]); } fn dequeue_any(&mut self) -> Vec { - match (self.cats.is_empty(), self.dogs.is_empty()) { - (true, true) => vec![-1, -1], - (true, false) => self.dequeue_dog(), - (false, true) => self.dequeue_cat(), - (false, false) => { - if self.dogs[0] < self.cats[0] { self.dequeue_dog() } else { self.dequeue_cat() } - } + if + self.q[0].is_empty() || + (!self.q[1].is_empty() && self.q[1].front().unwrap() < self.q[0].front().unwrap()) + { + self.dequeue_dog() + } else { + self.dequeue_cat() } } fn dequeue_dog(&mut self) -> Vec { - if self.dogs.is_empty() { - return vec![-1, -1]; + if self.q[1].is_empty() { + vec![-1, -1] + } else { + let dog = self.q[1].pop_front().unwrap(); + vec![dog, 1] } - vec![self.dogs.pop_front().unwrap(), 1] } fn dequeue_cat(&mut self) -> Vec { - if self.cats.is_empty() { - return vec![-1, -1]; + if self.q[0].is_empty() { + vec![-1, -1] + } else { + let cat = self.q[0].pop_front().unwrap(); + vec![cat, 0] } - vec![self.cats.pop_front().unwrap(), 0] } }/** * Your AnimalShelf object will be instantiated and called as such: diff --git a/lcci/03.06.Animal Shelter/Solution.cpp b/lcci/03.06.Animal Shelter/Solution.cpp new file mode 100644 index 0000000000000..3d5d60769c964 --- /dev/null +++ b/lcci/03.06.Animal Shelter/Solution.cpp @@ -0,0 +1,46 @@ +class AnimalShelf { +public: + AnimalShelf() { + } + + void enqueue(vector animal) { + q[animal[1]].push(animal[0]); + } + + vector dequeueAny() { + if (q[0].empty() || (!q[1].empty() && q[1].front() < q[0].front())) { + return dequeueDog(); + } + return dequeueCat(); + } + + vector dequeueDog() { + if (q[1].empty()) { + return {-1, -1}; + } + int dog = q[1].front(); + q[1].pop(); + return {dog, 1}; + } + + vector dequeueCat() { + if (q[0].empty()) { + return {-1, -1}; + } + int cat = q[0].front(); + q[0].pop(); + return {cat, 0}; + } + +private: + queue q[2]; +}; + +/** + * Your AnimalShelf object will be instantiated and called as such: + * AnimalShelf* obj = new AnimalShelf(); + * obj->enqueue(animal); + * vector param_2 = obj->dequeueAny(); + * vector param_3 = obj->dequeueDog(); + * vector param_4 = obj->dequeueCat(); + */ \ No newline at end of file diff --git a/lcci/03.06.Animal Shelter/Solution.go b/lcci/03.06.Animal Shelter/Solution.go new file mode 100644 index 0000000000000..3bbd97765aa77 --- /dev/null +++ b/lcci/03.06.Animal Shelter/Solution.go @@ -0,0 +1,45 @@ +type AnimalShelf struct { + q [2][]int +} + +func Constructor() AnimalShelf { + return AnimalShelf{} +} + +func (this *AnimalShelf) Enqueue(animal []int) { + this.q[animal[1]] = append(this.q[animal[1]], animal[0]) +} + +func (this *AnimalShelf) DequeueAny() []int { + if len(this.q[0]) == 0 || (len(this.q[1]) > 0 && this.q[0][0] > this.q[1][0]) { + return this.DequeueDog() + } + return this.DequeueCat() +} + +func (this *AnimalShelf) DequeueDog() []int { + if len(this.q[1]) == 0 { + return []int{-1, -1} + } + dog := this.q[1][0] + this.q[1] = this.q[1][1:] + return []int{dog, 1} +} + +func (this *AnimalShelf) DequeueCat() []int { + if len(this.q[0]) == 0 { + return []int{-1, -1} + } + cat := this.q[0][0] + this.q[0] = this.q[0][1:] + return []int{cat, 0} +} + +/** + * Your AnimalShelf object will be instantiated and called as such: + * obj := Constructor(); + * obj.Enqueue(animal); + * param_2 := obj.DequeueAny(); + * param_3 := obj.DequeueDog(); + * param_4 := obj.DequeueCat(); + */ \ No newline at end of file diff --git a/lcci/03.06.Animal Shelter/Solution.java b/lcci/03.06.Animal Shelter/Solution.java index d634369a3e221..89139660369b9 100644 --- a/lcci/03.06.Animal Shelter/Solution.java +++ b/lcci/03.06.Animal Shelter/Solution.java @@ -1,32 +1,27 @@ class AnimalShelf { - Queue cats; - Queue dogs; + private Deque[] q = new Deque[2]; + public AnimalShelf() { - cats = new LinkedList<>(); - dogs = new LinkedList<>(); + Arrays.setAll(q, k -> new ArrayDeque<>()); } public void enqueue(int[] animal) { - if (animal[1] == 0) { - cats.offer(animal[0]); - } else { - dogs.offer(animal[0]); - } + q[animal[1]].offer(animal[0]); } public int[] dequeueAny() { - return dogs.isEmpty() - ? dequeueCat() - : (cats.isEmpty() ? dequeueDog() - : (dogs.peek() < cats.peek() ? dequeueDog() : dequeueCat())); + if (q[0].isEmpty() || (!q[1].isEmpty() && q[1].peek() < q[0].peek())) { + return dequeueDog(); + } + return dequeueCat(); } public int[] dequeueDog() { - return dogs.isEmpty() ? new int[] {-1, -1} : new int[] {dogs.poll(), 1}; + return q[1].isEmpty() ? new int[] {-1, -1} : new int[] {q[1].poll(), 1}; } public int[] dequeueCat() { - return cats.isEmpty() ? new int[] {-1, -1} : new int[] {cats.poll(), 0}; + return q[0].isEmpty() ? new int[] {-1, -1} : new int[] {q[0].poll(), 0}; } } diff --git a/lcci/03.06.Animal Shelter/Solution.py b/lcci/03.06.Animal Shelter/Solution.py index c391b53e16734..080b75f6b0715 100644 --- a/lcci/03.06.Animal Shelter/Solution.py +++ b/lcci/03.06.Animal Shelter/Solution.py @@ -1,26 +1,22 @@ class AnimalShelf: + def __init__(self): - self.cats = [] - self.dogs = [] + self.q = [deque(), deque()] def enqueue(self, animal: List[int]) -> None: - if animal[1] == 0: - self.cats.insert(0, animal[0]) - else: - self.dogs.insert(0, animal[0]) + i, j = animal + self.q[j].append(i) def dequeueAny(self) -> List[int]: - if len(self.dogs) == 0: - return self.dequeueCat() - if len(self.cats) == 0: + if not self.q[0] or (self.q[1] and self.q[1][0] < self.q[0][0]): return self.dequeueDog() - return self.dequeueDog() if self.dogs[-1] < self.cats[-1] else self.dequeueCat() + return self.dequeueCat() def dequeueDog(self) -> List[int]: - return [-1, -1] if len(self.dogs) == 0 else [self.dogs.pop(), 1] + return [-1, -1] if not self.q[1] else [self.q[1].popleft(), 1] def dequeueCat(self) -> List[int]: - return [-1, -1] if len(self.cats) == 0 else [self.cats.pop(), 0] + return [-1, -1] if not self.q[0] else [self.q[0].popleft(), 0] # Your AnimalShelf object will be instantiated and called as such: diff --git a/lcci/03.06.Animal Shelter/Solution.rs b/lcci/03.06.Animal Shelter/Solution.rs index 8c325e39ddf93..687d5376e3d4e 100644 --- a/lcci/03.06.Animal Shelter/Solution.rs +++ b/lcci/03.06.Animal Shelter/Solution.rs @@ -1,53 +1,47 @@ use std::collections::VecDeque; struct AnimalShelf { - cats: VecDeque, - dogs: VecDeque, + q: [VecDeque; 2], } -/** - * `&self` means the method takes an immutable reference. - * If you need a mutable reference, change it to `&mut self` instead. - */ impl AnimalShelf { fn new() -> Self { - Self { - cats: VecDeque::new(), - dogs: VecDeque::new(), + AnimalShelf { + q: [VecDeque::new(), VecDeque::new()], } } fn enqueue(&mut self, animal: Vec) { - if animal[1] == 0 { - self.cats.push_back(animal[0]); - } else { - self.dogs.push_back(animal[0]); - } + self.q[animal[1] as usize].push_back(animal[0]); } fn dequeue_any(&mut self) -> Vec { - match (self.cats.is_empty(), self.dogs.is_empty()) { - (true, true) => vec![-1, -1], - (true, false) => self.dequeue_dog(), - (false, true) => self.dequeue_cat(), - (false, false) => { - if self.dogs[0] < self.cats[0] { self.dequeue_dog() } else { self.dequeue_cat() } - } + if + self.q[0].is_empty() || + (!self.q[1].is_empty() && self.q[1].front().unwrap() < self.q[0].front().unwrap()) + { + self.dequeue_dog() + } else { + self.dequeue_cat() } } fn dequeue_dog(&mut self) -> Vec { - if self.dogs.is_empty() { - return vec![-1, -1]; + if self.q[1].is_empty() { + vec![-1, -1] + } else { + let dog = self.q[1].pop_front().unwrap(); + vec![dog, 1] } - vec![self.dogs.pop_front().unwrap(), 1] } fn dequeue_cat(&mut self) -> Vec { - if self.cats.is_empty() { - return vec![-1, -1]; + if self.q[0].is_empty() { + vec![-1, -1] + } else { + let cat = self.q[0].pop_front().unwrap(); + vec![cat, 0] } - vec![self.cats.pop_front().unwrap(), 0] } }/** * Your AnimalShelf object will be instantiated and called as such: diff --git a/lcci/03.06.Animal Shelter/Solution.ts b/lcci/03.06.Animal Shelter/Solution.ts index 88e7b7c5ab1e7..c7ff7ec236c38 100644 --- a/lcci/03.06.Animal Shelter/Solution.ts +++ b/lcci/03.06.Animal Shelter/Solution.ts @@ -1,42 +1,31 @@ class AnimalShelf { - private cats: number[]; - private dogs: number[]; - - constructor() { - this.cats = []; - this.dogs = []; - } + private q: number[][] = [[], []]; + constructor() {} enqueue(animal: number[]): void { const [i, j] = animal; - this[j === 0 ? 'cats' : 'dogs'].push(i); + this.q[j].push(i); } dequeueAny(): number[] { - const n = this.dogs.length; - const m = this.cats.length; - if (n === 0 && m === 0) { - return [-1, -1]; - } - if ((this.dogs[0] ?? Infinity) < (this.cats[0] ?? Infinity)) { - return [this.dogs.shift(), 1]; - } else { - return [this.cats.shift(), 0]; + if (this.q[0].length === 0 || (this.q[1].length > 0 && this.q[0][0] > this.q[1][0])) { + return this.dequeueDog(); } + return this.dequeueCat(); } dequeueDog(): number[] { - if (this.dogs.length === 0) { + if (this.q[1].length === 0) { return [-1, -1]; } - return [this.dogs.shift(), 1]; + return [this.q[1].shift()!, 1]; } dequeueCat(): number[] { - if (this.cats.length === 0) { + if (this.q[0].length === 0) { return [-1, -1]; } - return [this.cats.shift(), 0]; + return [this.q[0].shift()!, 0]; } }