用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )。
其中:
1 <= values <= 10000最多会对 appendTail、deleteHead 进行 10000 次调用 示例 1: 输入: ["CQueue","appendTail","deleteHead","deleteHead"] [[],[3],[],[]] 输出:[null,null,3,-1] 示例 2: 输入: ["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"] [[],[],[5],[2],[],[]] 输出:[null,-1,null,null,5,2]
用两个栈实现一个队列的功能,即通过两个先入后出(FILO)实现一个先入先出(FIFO),我们可以用一个栈支持插入操作,另一个栈实现删除操作。
具体的操作为:当我们每一次执行插入元素时,直接往第一个栈 stack1 插入元素,根据栈的结构特性,栈底是第一个插入也是下一个待删除的元素,栈顶是最后插入的元素。当我们想执行删除操作时,需要将 stack1 的元素依次取出,取到最后才能访问到该删除的元素,但同时我们也想保持元素插入的顺序,这时就可以用上第二个栈 stack2。假设第一次执行删除时,stack2位空,则先把 stack1 的元素依次弹出并插入到 stack2 中,直至 stack1完全清空,此时 stack2 的栈顶即为下一个待删除的元素,直至栈底依次为接下来待删除的元素。此后,每次执行删除操作只需从 stack2 弹出元素即可。
当 stack2 栈内存在元素的时候,删除与插入操作分别对 stack2 与 stack1进行操作,且两个栈之间相互独立。即删除操作只在 stack2 进行,插入操作只在 stack1 进行。在 stack2 清空之前,stack1 维持后一批插入的元素及其插入顺序。每次当且仅当 stack2 为空,且需要进行删除操作时,才从 stack1 向 stack2 转移数据。如果转移后 stack2 仍为空,即此时无元素存在,则返回 -1。
class CQueue { private Stack<Integer> stack1; private Stack<Integer> stack2; public CQueue() { stack1 = new Stack<>(); stack2 = new Stack<>(); } public void appendTail(int value) { stack1.push(value); } public int deleteHead() { if (!stack2.isEmpty()) { return stack2.pop(); } else { while (!stack1.isEmpty()) { stack2.push(stack1.pop()); } if (stack2.isEmpty()) { return -1; } else { return stack2.pop(); } } } }