day10 | 用栈实现队列、用队列实现栈、有效的括号、删除字符串中的所有相邻重复项

目录

用栈实现队列

用队列实现栈

 有效的括号

删除字符串中的所有相邻重复项


用栈实现队列

题目链接:232. 用栈实现队列

---请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

这里直接给代码 了:

class MyQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;

    public MyQueue() {
        stack1 = new Stack();
        stack2 = new Stack();

    }
    
    //直接将元素x压入第一个栈
    public void push(int x) {
        stack1.push(x);
    }
    
    public int pop() {
        //注意:待第二个栈为空时,再填充第一个栈的元素进去,不然进出顺序会出问题
        if(stack2.isEmpty())
        reverse();
        return  stack2.pop();
    }
    
    public int peek() {
        //注意:待第二个栈为空时,再填充第一个栈的元素进去
        if(stack2.isEmpty())
        reverse();
        return stack2.peek();
    }
    
    public boolean empty() {
        return stack1.isEmpty() && stack2.isEmpty();
    }

    //定义一个方法:将第一个栈的元素全部填充进第二个栈
    public void reverse(){
        while(!stack1.isEmpty()){
            stack2.push(stack1.pop());
        }
    }
}

用队列实现栈

题目链接:225. 用队列实现栈

---请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

思路:

queue1:该队列放的元素跟栈元素放出的顺序一致,例如压入1,2,3三个元素,栈元素:1,2,3;queue1元素:3,2,1。

queue2:辅助队列

push操作时,先让queue2接收,若queue1不为空,则将1队列的元素放入2队列中,此时2队列放的元素跟栈元素放出的顺序一致,最后交换1队列和2队列即可

class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;
    Queue<Integer> queue;

    public MyStack() {
        queue1 = new LinkedList();
        queue2 = new LinkedList();

    }
    
    public void push(int x) {
        queue2.offer(x); // 先放在辅助队列中
        while (!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        Queue<Integer> queueTemp;
        queueTemp = queue1;
        queue1 = queue2;
        queue2 = queueTemp; // 最后交换queue1和queue2,将元素都放到queue1中
    }
    
    public int pop() {
        return queue1.poll(); // 因为queue1中的元素和栈中的保持一致,所以这个和下面两个的操作只看queue1即可
    }
    
    public int top() {
        return queue1.peek();
    }
    
    public boolean empty() {
        return queue1.isEmpty();
    }
}

 有效的括号

题目链接:20. 有效的括号

---给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

思路:这里一共有三种不匹配的情况

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

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

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

第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。

class Solution {
    public boolean isValid(String s) {
        Stack<Character> st = new Stack<>();
        char[] ch = s.toCharArray();
        //这里为方便之后左右括号匹配,遍历到左括号时就将其对应的右括号压进栈
        for(int i = 0; i < ch.length; i++){
            if(ch[i] == '(')st.push(')');
            else if(ch[i] == '[')st.push(']');
            else if(ch[i] == '{')st.push('}');
            else if(st.isEmpty() || ch[i] != st.peek())//前者栈已经为空,对应第三种情况;后者匹配不对,对应第二种情况
            return  false;
            else
            st.pop();//本次循环匹配成功,将栈顶元素压出栈
        }

        return st.isEmpty();
    }
}

删除字符串中的所有相邻重复项

题目链接:1047. 删除字符串中的所有相邻重复项 

---给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

思路:创建一个栈空间,然后遍历字符串,将每个字符与栈顶元素比较,若相等,则出栈一个元素,反之则将字符压入栈空间。需要注意的是,当栈为空时不能比较,直接将当前字符压入栈即可。

class Solution {
    public String removeDuplicates(String s) {
        char[] ch = s.toCharArray();
        Stack<Character> stack = new Stack<>();
        for(char c : ch){
            if(stack.isEmpty())
                stack.push(c);
            else{
                if(c != stack.peek())stack.push(c);
                else{
                    stack.pop();
                }
            }
        }
        //字符拼接,用StringBuilder更快!!
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty())sb.append(stack.pop());
        return sb.reverse().toString();
    }
}

 

  • 25
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值