Skip to content

Instantly share code, notes, and snippets.

@yanfeng42
Created January 5, 2024 06:35
Show Gist options
  • Save yanfeng42/feb4df6c1b2817133e29de94ec5f5c45 to your computer and use it in GitHub Desktop.
Save yanfeng42/feb4df6c1b2817133e29de94ec5f5c45 to your computer and use it in GitHub Desktop.
1.3.49栈与队列。用有限个栈实现一个队列,保证每个队列操作(在最坏的情况下)都只需要常数次的栈操作。警告:非常难!
package study.algorithm;
import edu.princeton.cs.algs4.StdOut;
public class QueueFromSevenStack<Item> {
private boolean isRevert = false; // 是否在反转 Stack.
private boolean isConcat = false; // 是否在拼接 Stack.
private Stack<Item> T = new Stack<>(); // 队列尾部,用于 enqueue 入队操作.
private Stack<Item> H = new Stack<>(); // 队列头部, 用于 dequeue 出队操作.
private Stack<Item> TS = new Stack<>(); // 暂存 T 中的数据.
private Stack<Item> TR = new Stack<>(); // T 反转后的数据,后续会拼接 HR 中的元素.
private Stack<Item> TRC = new Stack<>(); // TR 的副本, 与T中元素完全一致.
private Stack<Item> HR = new Stack<>(); // H 反转后的数据.
private Stack<Item> HC = new Stack<>(); // H 的副本, 初始与H中的元素完全一致.
private Integer dequeueItemCount = 0; // 在 反转或拼接Stack过程中, 出队的元素数量.
public void enqueue(Item item) {
T.push(item);
process(true);
}
public Item dequeue() {
if(H.isEmpty()){
return null;
}
Item item = H.pop();
process(false);
return item;
}
private void process(Boolean isEnqueue) {
if(!isEnqueue){
if(isRevert || isConcat){
dequeueItemCount += 1;
} else {
// 一种特殊情况: 仅存在 dequeue 操作时,直接 pop H的副本, 不用额外计数.
HC.pop();
}
}
if (!isRevert && !isConcat && !T.isEmpty() && T.size() >= H.size()) {
// 仅在必要时进入 Revert Stack阶段.
TS = T;
T = new Stack<>();
isRevert = true;
}
if (isRevert) {
if (!TS.isEmpty()) {
Item item = TS.pop();
TR.push(item);
TRC.push(item);
}
if (!HC.isEmpty()) {
Item item = HC.pop();
HR.push(item);
}
}
if (TS.isEmpty() && HC.isEmpty()) {
isRevert = false;
isConcat = true;
}
if (isConcat) {
if (!HR.isEmpty() && HR.size() > dequeueItemCount) {
Item item = HR.pop();
TR.push(item);
TRC.push(item);
}
if (HR.isEmpty() || HR.size() == dequeueItemCount) {
H = TR;
HC = TRC;
TR = new Stack<>();
TRC = new Stack<>();
HR = new Stack<>();
isConcat = false;
dequeueItemCount = 0;
}
}
}
public static void main(String[] args) {
QueueFromSevenStack<Integer> q = new QueueFromSevenStack<>();
StdOut.println("enqueue 0");
q.enqueue(0);
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("enqueue 1");
q.enqueue(1);
StdOut.println("enqueue 2~3");
q.enqueue(2);
q.enqueue(3);
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("enqueue 4 ~ 6");
q.enqueue(4);
q.enqueue(5);
q.enqueue(6);
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("enqueue 7 ~ 10");
q.enqueue(7);
q.enqueue(8);
q.enqueue(9);
q.enqueue(10);
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("dequeue: " + q.dequeue());
StdOut.println("dequeue: " + q.dequeue());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment