Day10
前言
今天开始栈与队列了,也是不太熟悉的知识,好好加油
文章:代码随想录
LeetCode 232 用栈实现队列
自己思路
遵循建议,先看视频
看完讲解
真的很奇妙输入栈+输出栈,两个栈就可以实现队列。入栈不必多说,出栈的话需要注意:首先需要把入栈中的全部元素弹出并全部放进出栈中,并且一定要保证出栈为空的时候放(没空就先弹出元素直到为空),这两点没注意的话都会影响到元素的顺序被打乱
因为没有接触过栈和队列的Java代码,所以这里遇到不会的就先去参考答案,这里还需要注意的是peek函数因为和pop函数代码有许多重合的地方,其实就可以直接调用pop函数,接收的值就是peek函数要返回的值,但是记得要把pop出来的元素再重新push进去就可以,这样就提高了代码的简洁性。另外empty函数只需要判断入栈和出栈是否都为空,毕竟是两个栈实现的这个队列,如果如果两个栈都空了就说明队列为空了
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
public MyQueue() {
stackIn = new Stack<>();
stackOut = new Stack<>();
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
if (stackOut.isEmpty()) {
while (!stackIn.isEmpty()) {
stackOut.push(stackIn.peek());
stackIn.pop();
}
}
int result = stackOut.peek();
stackOut.pop();
return result;
}
public int peek() {
int result = this.pop();
stackOut.push(result);
return result;
}
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
}
LeetCode 225 用队列实现栈
自己思路
遵循建议,先看视频
看完讲解
写代码的时候发现确实不清楚队列的定义和操作,比如这里加入和弹出用到的是add和poll。总体来看,用一个队列就实现栈的主要思路是队列弹出再重新加入,还是入队列就不用多说,出队列的话因为其实是想要最后一个元素出队列,所以就把除了最后一个元素外的所有元素都依次出队列再重新入队列,这样这个元素就可以成功的出队列了。然后在top函数中,与上一题类似,我还是直接调用pop函数就可以获取到想要的元素,但是要记得再把这个元素添加到队列中,这样就可以完成并且也不会改变元素的顺序
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
}
public int pop() {
for (int i = 0; i < queue.size()-1; i++) {
int temp = queue.poll();
queue.add(temp);
}
int result = queue.peek();
queue.poll();
return result;
}
public int top() {
int result = this.pop();
queue.add(result);
return result;
}
public boolean empty() {
return queue.isEmpty();
}
}
总结
用时:2.5h,今天的题目直接看了视频之后还算简单
栈的定义和操作
// 栈的定义
Stack<Integer> stack = new Stack<>();
// 栈加入元素
stack.push(x);
// 栈移除并返回元素(出口的)
stack.pop();
// 栈返回元素(出口的)
stack.peek();
// 栈大小
stack.size();
// 栈空否
stack.isEmpty();
队列的定义和操作
一般都是用Queue类型来定义,后面是LinkedList<>()或者ArrayDeque<>()都可以,两者后续的操作代码也是一样的,一般我更喜欢采用LinkedList<>()
// 队列的定义
Queue<Integer> queue = new LinkedList<>();
// 或者
Queue<Integer> queue = new ArrayDeque<>();
// 队列加入元素(从入口)
queue.add(x);
// 队列移除并返回元素(出口的)
queue.poll();
// 队列返回元素(出口的)
queue.peek();
// 队列大小
queue.size();
// 队列空否
queue.isEmpty();
其实还可以使用Deque类型来定义,后面也是LinkedList<>()或者ArrayDeque<>()都可以,Deque类型和Queue类型的区别主要在于:Queue是队列,只允许在入口添加元素,在出口移除元素;而Deque是双端队列,它既可以在入口也可以在出口添加元素,既可以在入口也可以在出口移除元素
// 双端队列的定义
Deque<Integer> deque = new LinkedList<>();
// 或者
Deque<Integer> deque = new ArrayDeque<>();
// 理解入口为Last 出口为First
// 双端队列加入元素(从出口)
deque.addFirst(x);
// 双端队列加入元素(从入口) 等效于 Queue的add()
deque.addLast(x);
// 或者
deque.add(x);
// 双端队列移除并返回元素(出口的) 等效于 Queue的poll()
deque.pollFirst();
// 或者
deque.poll();
// 双端队列移除并返回元素(入口的)
deque.pollLast();
// 双端队列返回元素(出口的) 等效于 Queue的peek()
deque.peekFirst();
// 或者
deque.peek();
// 双端队列返回元素(入口的)
deque.peekLast();
// 双端队列大小
deque.size();
// 双端队列空否
deque.isEmpty();
脑子有点乱,我觉得目前对我来说,如果只是需要单边操作的话,还是用Queue吧,简洁明了
另外当使用Deque类型来定义时,它会既可以被用作栈,也可以被用作队列,具体是哪个要看后面如何操作它
总结来说:主要看的是前面的变量类型,如果是Queue那就是队列,如果是Deque那就是队列和栈都可以