代码随想录第十一天

内容:

  1. 用栈实现队列(232)
  2. 用队列实现栈(225)
  3. 有效的括号(20)
  4. 删除字符串中的所有相邻重复项(1047)

1.用栈实现队列

难度:🔥

1.1 思路分析

这道题目我们只需要使用两个栈即可解决

如图所示:

232.用栈实现队列版本2
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 收获总结
  • 灵活运用Stackpush(),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中的 addLastpollFirstpeekFirst

3.有效的括号

难度:🔥🔥

3.1 思路分析

这题在于我们为什么要考虑使用栈这个结构?

实际上括号匹配是使用栈解决的经典问题,由于栈结构的特殊性,非常适合做对称匹配类的题目。

此时我们需要分析不匹配的三种情况:

  1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 括号匹配1

  2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。 括号匹配2

  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配。 括号匹配3

    动画如下:

    20.有效括号
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 思路分析

这题我们依然考虑使用栈结构来解决问题

那么栈里应该放的是什么元素呢?

我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?

所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。然后去做对应的删除操作

如图:

1047.删除字符串中的所有相邻重复项
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 收获总结
  • 在考虑相同元素的消除时,栈会是我们需要思考使用的一个数据结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值