内容:
- 用栈实现队列(232)
- 用队列实现栈(225)
- 有效的括号(20)
- 删除字符串中的所有相邻重复项(1047)
1.用栈实现队列
难度:🔥
1.1 思路分析
这道题目我们只需要使用两个栈即可解决
如图所示:
1.2 代码实现
使用两个栈,一个用于进栈,一个用于出栈来实现
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() {
dumpStackIn();
return stackOut.pop();
}
public int peek() {
dumpStackIn();
return stackOut.peek();
}
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
//将入栈的元素加入到出栈中
private void dumpStackIn(){
if (!stackOut.isEmpty()) return;
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
}
1.3 收获总结
- 灵活运用
Stack
的push(),pop(),peek(),isEmpty()
等方法
2.用队列实现栈
难度:🔥
2.2 思路分析
这题我们可以使用两个队列或者一个队列来实现
对于一个队列我们只需要在弹出数据的时候让队列的前面的元素加到队列的尾部,然后把队列的头部元素弹出即可
2.2 代码实现
使用一个
Deque(双端队列)
class MyStack {
//使用一个Deque来解决
Deque<Integer> deque;
public MyStack() {
deque = new ArrayDeque<>();
}
public void push(int x) {
deque.addLast(x);
}
public int pop() {
int size = deque.size();
for(int i = 0;i < size - 1;i++){
deque.addLast(deque.peekFirst());
deque.pollFirst();
}
int result = deque.pollFirst();
return result;
}
public int top() {
return deque.peekLast();
}
public boolean empty() {
return deque.isEmpty();
}
}
2.3 收获总结
-
Deque
接口继承了Queue
接口
所以 Queue 中的 add、poll、peek等效于Deque
中的addLast
、pollFirst
、peekFirst
3.有效的括号
难度:🔥🔥
3.1 思路分析
这题在于我们为什么要考虑使用栈这个结构?
实际上括号匹配是使用栈解决的经典问题,由于栈结构的特殊性,非常适合做对称匹配类的题目。
此时我们需要分析不匹配的三种情况:
-
第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
-
第二种情况,括号没有多余,但是 括号的类型没有匹配上。
-
第三种情况,字符串里右方向的括号多余了,所以不匹配。
动画如下:
3.2 代码实现
class Solution {
public boolean isValid(String s) {
Deque<Character> deque = new ArrayDeque<>();
char ch;
for(int i = 0;i < s.length();i++){
ch = s.charAt(i);
if (ch == '('){
deque.push(')');
}else if (ch == '['){
deque.push(']');
}else if(ch == '{'){
deque.push('}');
}else if (deque.isEmpty() || deque.peek() != ch){//注意peek()与pop()的区别
//如果此时栈为空,而还没遍历完元素则返回false;若此时元素与栈顶不相等也返回 false
return false;
}else{
deque.pop();
}
}
return deque.isEmpty();
}
}
3.3 收获总结
- 多看多练,对于这类问题一定要思考好方向,找出特殊情况再去写代码
4.删除字符串中的所有相邻重复项
难度:🔥🔥
4.1 思路分析
这题我们依然考虑使用栈结构来解决问题
那么栈里应该放的是什么元素呢?
我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?
所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。然后去做对应的删除操作
如图:
4.2 代码实现
使用双端队列
Deque
class Solution {
public String removeDuplicates(String S) {
//方法一:使用Deque双端队列
Deque<Character> deque = new ArrayDeque<>();
for(int i = 0;i < s.length();i++){
char ch = s.charAt(i);
if (deque.isEmpty() || deque.peek() != ch) {
deque.push(ch);
}else{
deque.pop();
}
}
String str = "";
while(!deque.isEmpty()){
str = deque.pop() + str;//对于"abbaca"一开始pop()'a',后来pop()'c'与‘a'连接
}
return str;
}
}
拿字符串直接作为堆栈
class Solution {
public String removeDuplicates(String S) {
StringBuffer sb = new StringBuffer();
int top = - 1;
for(int i = 0;i < s.length();i++){
char ch = s.charAt(i);
if (top >= 0 && sb.charAt(top) == ch){
sb.deleteCharAt(top);
top--;
}else{
sb.append(ch);
top++;
}
}
return sb.toString();
}
}
4.3 收获总结
- 在考虑相同元素的消除时,栈会是我们需要思考使用的一个数据结构