目录
题目链接:232. 用栈实现队列 - 力扣(LeetCode)
题目链接:225. 用队列实现栈 - 力扣(LeetCode)
题目链接:1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
The longest way must have its close; the gloomiest night will on to a morning.
题目链接:232. 用栈实现队列 - 力扣(LeetCode)
用两个栈实现一个队列,思路如下:
- 使用两个栈
stack1
和stack2
。stack1
用于处理入队操作,stack2
用于处理出队和取队首操作; - 入队操作将元素推入
stack1;
- 出队操作从
stack2
弹出元素。如果stack2
为空,则将stack1
中的所有元素弹出并推入stack2
,然后从stack2
弹出元素; - 取队首操作类似于出队操作,只是不弹出元素;
- 判断队列是否为空,只需检查
stack1
和stack2
是否都为空;
class MyQueue232 {
// 使用两个栈实现一个队列
private Stack<Integer> stack1;
private Stack<Integer> stack2;
public MyQueue232() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public void push(int x) {
stack1.push(x);
}
public int pop() {
if (stack2.isEmpty()) { // 如果stack2为空,则将stack1的所有元素弹出并推入stack2
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop(); // 从 stack2 弹出元素
}
public int peek() {
if (stack2.isEmpty()) {
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.peek(); // 从 stack2 获取队首元素
}
public boolean empty() {
return stack1.empty() && stack2.isEmpty();
}
}
题目链接:225. 用队列实现栈 - 力扣(LeetCode)
使用两个队列来实现一个栈,我们可以利用一个主队列queue1
和一个辅助队列queue2
来模拟栈的后进先出,思路如下(注意到其实不用queue2
也可以实现,不管是增加元素还是删除元素的操作后,辅助队列queue2
始终为空):
- 使用两个队列
queue1
和queue2
,其中queue1
用于存储栈的元素,queue2
用作辅助队列; push(x)
操作将元素入队到queue2
,然后将queue1
中的所有元素依次出队并入队到queue2
。最后,交换queue1
和queue2;
pop()
操作直接从queue1
中出队一个元素;top()
操作直接返回queue1
的队首元素;empty()
操作检查queue1
是否为空;
class MyStack225 {
private Queue<Integer> queue1;
private Queue<Integer> queue2;
public MyStack225() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
queue2.offer(x); // 元素入队到queue2
while (!queue1.isEmpty()){ // 将 queue1 中的所有元素依次出队并入队到 queue2
queue2.offer(queue1.poll());
}
// 交换queue1和queue2
Queue<Integer> temp = queue1;
queue1 = queue2;
queue2 = temp;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty(); // queue2 始终为空
}
}
题目链接:20. 有效的括号 - 力扣(LeetCode)
使用栈解决的经典问题。思路:在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了。
class Solution20 {
public boolean isValid(String s) {
// 使用栈解决括号匹配问题
// 在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了
if (s.length() % 2 != 0) return false; // s长度为奇数 返回false
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i) == '(')
stack.push(')');
else if (s.charAt(i) == '[') {
stack.push(']');
} else if (s.charAt(i) == '}') {
stack.push('}');
} else if (stack.isEmpty() || stack.peek() != s.charAt(i)){
return false;
}else {
stack.pop();
}
}
return stack.isEmpty();
}
}
题目链接:1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
使用栈解决删除字符串重复相邻项。思路:如果当前字符与栈顶字符相同,则弹出栈顶字符;如果不同,则将当前字符压入栈中。
class Solution1047 {
public String removeDuplicates(String s) {
/**
* 1 如果当前字符与栈顶字符相同,则弹出栈顶字符。
* 2 如果不同,则将当前字符压入栈中。
*/
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()){
if (!stack.isEmpty() && stack.peek() == c){
stack.pop();
}else {
stack.push(c);
}
}
StringBuilder result = new StringBuilder();
for (char c : stack){
result.append(c);
}
return result.toString();
}
}
-----------------------------------------------------------------------------------------------------------------------
最后记录一点:
前面两个问题中,创建栈我使用的 Stack<Character> stack = new Stack<>();
这其实是Java中老旧的栈对象实现方法了,而官方推荐使用 Deque
来替代 Stack。
因为 Deque
接口提供了更全面和灵活的操作,并且它是接口,具有更好的扩展性。其中栈相关的函数名不变,只需将Stack<Character> stack = new Stack<>()
替换成Deque<Character> stack = new LinkedList<>();
就可以了。
Deque
是双端队列,支持在两端插入和删除元素。操作上可以使用 addFirst
和 addLast
来在两端插入元素,removeFirst
和 removeLast
来在两端删除元素,peekFirst
和 peekLast
来访问两端的元素。其更通用,可以用来实现栈和队列的功能。