算法刷题Day10 - 栈与队列part1|栈与队列基础|LC.232 用栈实现队列|LC.225 用队列实现栈|LC20.有效的括号|LC1047. 删除字符串中所有相邻重复项

栈与队列基础

  • 栈(stack):先进后出(LIFO),常见操作有 push()pop()peek()isEmpty()
  • 队列(queue):先进先出(FIFO),常见操作有 offer()/add()poll()/remove()peek()isEmpty()

栈和队列的操作的时间复杂度一般是O(1) 

LeetCode - 232. Implement Queue using Stacks 用栈实现队列

解题目标:用栈来实现一个FIFO队列

解题思路:用两个栈来模拟队列,先把所有元素入栈stackIn,再依次出栈放到另一个stackOut栈中。stackIn相当于一个暂存区,关键是出栈的逻辑,假如stackOut的元素还没出完是不能添加进去的,否则顺序就乱了,必须先判断stackOut是否为空才能从stackIn出栈再全部加入。比如下面这个例子一次性加入元素1,2,3,使用pop()后stackOut依然残留元素2,3。这个时候假如push(4),stackIn就不能直接添加到stackOut了。

注意事项:必须要等stackOut全部出栈之后才能让stackIn出栈的元素进栈到stackOut。

class MyQueue {
    //we need two stacks here
    Stack<Integer> stackIn;
    Stack<Integer> stackOut;

    public MyQueue() {
        // initialize two stacks
        stackIn = new Stack<>();
        stackOut = new Stack<>();
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        if (stackOut.isEmpty()) {
            while (!stackIn.isEmpty()) {
                stackOut.push(stackIn.pop()); 
            }
        } 
        return stackOut.pop();
    }
    
    public int peek() {
        if (stackOut.isEmpty()) {
            while (!stackIn.isEmpty()) {
                stackOut.push(stackIn.pop());
            }
        }
        return stackOut.peek();
    }
    
    public boolean empty() {
        return stackOut.isEmpty() && stackIn.isEmpty();
    }
}

LeetCode - 225. Implement Stack using Queues 用队列实现栈

解题思路:这题可以只用一个队列来达到目的,在pop的时候得到的是栈的顶层元素,但在队列中就相当于弹出队列中最后一个元素,队列中能够弹出的也只能是头一个元素,因此每一次push就把第1~n-1个元素重新排列进队列即可。

class MyStack {
    Queue<Integer> q;

    public MyStack() {
        q = new LinkedList<>();
    }
    
    public void push(int x) {
        q.add(x);
        //每次添加都把前面的元素全部重新进入队列
        int queueSize = q.size();
        while (queueSize-- > 1) {
            q.add(q.poll());
        }
    }
    
    public int pop() {
        return q.poll();
    }
    
    public int top() {
        return q.peek();
    }
    
    public boolean empty() {
        return q.isEmpty();
    }
}

LeetCode - 20. Valid Parentheses 有效的括号

解题目标:检查字符串中的括号等类似符号是否正确闭合

解题思路:在碰到左符号时,在栈中加入右符号,碰到右符号就和栈顶元素进行比对。注意必须是遍历完成后stack刚好为空才证明匹配成功,中途就空了说明右符号多了。

import java.nio.charset.Charset;class Solution {
    public boolean isValid(String s) {
        Stack<Character> charStack = new Stack<>();
        for (char c : s.toCharArray()) {
            if (c == '[' || c == '(' || c == '{') {
                if (c == '[' ) {
                    charStack.add(']');
                } else if (c == '(') {
                    charStack.add(')');
                } else {
                    charStack.add('}');
                }
            } else {
                if (charStack.isEmpty()) {
                    return false;
                } else {
                    if (c == charStack.peek()) {
                        charStack.pop();
                    } else {
                        return false;
                    }
                }
            }
        }
        return charStack.isEmpty();
    }
}

LeetCode - 1047. 删除字符串中所有相邻重复项

解题思路:新建一个栈并且遍历字符串中的字母并且同时与栈顶比较,如果和栈顶元素一样则移除,如果不一样就加入栈,最后剩下的就是没有匹配成功的字母,也就是需要求出的结果。这题最后的结果需要的是删除后的字符串,因此这里没有必要真正去建立一个栈,而是可以用字符串来模拟栈的运作方式。

class Solution {
    public String removeDuplicates(String s) {
        String res = ""; // string as stack
        for (int i = 0; i < s.length(); i++) {
            if (res.length() > 0 && s.charAt(i) == res.charAt(res.length() - 1)) {
                res  = res.substring(0, res.length() - 1);
            } else {
                res += s.charAt(i);
            }
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值