Day10 栈和队列
基础知识
栈(Stack)
Java的java.util.Stack
类是一个后进先出(LIFO)的数据结构,以下是一些常用的方法:
push(E item)
: 将一个元素压入栈顶。pop()
: 移除并返回栈顶元素。peek()
: 返回栈顶元素但不移除它。empty()
: 检查栈是否为空。search(Object o)
: 返回对象在栈中的位置,从1开始计数。
队列(Queue)
Java的java.util.Queue
接口是一个队列的抽象,它定义了队列的基本操作。以下是一些实现Queue
接口的常用类和它们的API:
add(E e)
: 向队列添加一个元素。如果队列容量限制,则抛出IllegalStateException
。offer(E e)
: 向队列添加一个元素。如果队列容量限制,返回false
。remove()
: 移除并返回队列头部元素。如果队列为空,则抛出NoSuchElementException
。poll()
: 移除并返回队列头部元素。如果队列为空,则返回null
。element()
: 返回队列头部元素但不移除它。如果队列为空,则抛出NoSuchElementException
。peek()
: 返回队列头部元素但不移除它。如果队列为空,则返回null
。
以下是一些实现Queue
接口的Java类:
ArrayBlockingQueue
: 一个固定大小的线程安全队列。LinkedBlockingQueue
: 一个可选的固定大小的线程安全队列。PriorityQueue
: 一个基于优先级的队列,元素按照自然顺序或根据提供的比较器排序。LinkedList
: 一个双向链表实现的队列,可以作为队列使用。
双端队列(Deque)
Java的java.util.Deque
接口扩展了Queue
接口,允许元素在两端添加或移除,以下是一些实现Deque
接口的类:
ArrayDeque
: 一个基于数组的双端队列实现,通常比LinkedList
更高效。
以下是Deque
的一些常用方法:
addFirst(E e)
: 在双端队列的开头添加一个元素。addLast(E e)
: 在双端队列的末尾添加一个元素。removeFirst()
: 移除并返回双端队列的开头元素。removeLast()
: 移除并返回双端队列的末尾元素。push(E e)
: 将一个元素推入双端队列的开头,类似于栈操作。pop()
: 移除并返回双端队列的开头元素,也类似于栈操作。
题目
232
较为简单的模拟题,对其中辅助函数的理解不是很深:本质上是把In栈里面前面的放到Out里面。
疑问点:In和Out里面的区别和联系–In里面只是一部分,要把所有的数据抽象地看成是一部分一部分的这样就可以 理解啦
225
用两个队列模拟栈和用两个栈模拟队列的思路是完全不一样的;这里的第二个队列是起到辅助作用,而不是像两个栈模拟队列一样是起到协同作用的。
在代码中,我们主要的栈就是queue1。
20
经典的括号匹配问题;不是很难,但是逻辑得清楚:
被放入栈的条件:
-
可能是目前栈为空
-
可能是当前的字符和栈顶的不一样(!!注意是两种条件)
1047
和匹配括号是相似的,难度不是很大,但是要熟悉相关的字符串api,不然还是做不下去
代码
232
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
/** Initialize your data structure here. */
public MyQueue() {
stackIn = new Stack<>(); // 负责进栈
stackOut = new <>(); // 负责出栈
}
/** Push element x to the back of queue. */
public void push(int x) {
stackIn.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
dumpstackIn();
return stackOut.pop();
}
/** Get the front element. */
public int peek() {
dumpstackIn();
return stackOut.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
// 如果stackOut为空,那么将stackIn中的元素全部放到stackOut中
private void dumpstackIn(){
if (!stackOut.isEmpty()) return;
while (!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
}
225
class MyStack {
Queue<Integer>queue1;
Queue<Integer>queue2;
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
queue2.offer(x);
while(!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
Queue temp = new LinkedList<>();
temp = queue2;
queue2 = queue1;
queue1 = temp;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
20
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
switch (c) {
case '{':
case '(':
case '[':
stack.push(c);
break;
case '}':
if (stack.isEmpty() || stack.pop() != '{') return false;
break;
case ')':
if (stack.isEmpty() || stack.pop() != '(') return false;
break;
case ']':
if (stack.isEmpty() || stack.pop() != '[') return false;
break;
default:
return false;
}
}
return stack.isEmpty();
}
}
1047
class Solution {
public String removeDuplicates(String s) {
Stack<Character> stack = new Stack<>();
Stack<Character> temp = new Stack<>();
for(char c : s.toCharArray()){
if(stack.isEmpty() || c != stack.peek()){
stack.push(c);
}else{
stack.pop();
}
}
StringBuilder sb = new StringBuilder();
while(!stack.isEmpty()){
temp.push(stack.pop());
}
while(!temp.isEmpty()){
char cv = temp.pop();
sb.append(cv);
}
return sb.toString();
}
}