栈与队列——232,225,20

今天开始学习栈和队列,第一天的题目都较为简单,用栈模拟队列,用队列模拟栈,以及一道栈的经典应用题目。

LeetCode232.用栈实现队列

用栈实现队列
本题和后面一题都锻炼了对栈和队列特点的运用。栈是先入后出,队列是先入先出,如果他们的进入顺序相同,退出的顺序将会是相反的。既然如此,结合题目使用两个栈,那么我们很容易可以想到,否定之否定为肯定,即二次取反不会改变原来的顺序。具体来说就是,如果出队的顺序为原顺序,那么出栈的顺序将会颠倒,编程相反的顺序,那么再进行一次出栈,再次颠倒,就会编程原来的出队顺序。理论成立,我们可以开始模拟,在模拟的时候,会发现有另外一种情况,当栈内元素没有出干净,这时入栈,将会打乱原有顺序,需要我们再次思考,应该怎么调配这些元素,使他们顺序保持不变。

public class MyQueue {

    static Stack<Integer> stack1;
    static Stack<Integer> stack2;
    public  MyQueue(){
        stack1=new Stack<>();
        stack2=new Stack<>();
    }

    public static void push(int x){
        stack1.push(x);
    }

    public static int pop(){
        if (stack2.isEmpty()){
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }

    public static int peek(){
        if (stack2.isEmpty()){
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }

    public static boolean empty(){
        if (stack1.empty()&& stack2.empty()){
            return true;
        }else {
            return false;
        }
    }

}

我们定义两个栈,stack1为入队栈,stack2为出队栈,入队时,将元素push进入队栈即可。在出队时,需要注意顺序,首先将入队栈的每个元素出栈后再次push进出队栈,这样顺序就会恢复进入的顺序。之后考虑特殊情况,即如果没出干净就进栈,将会打乱顺序,所以我们可以将stack1当作存储区,如果stack2中没有元素,即可以将stack1中的元素push进stack2中,如果stack2中仍留有元素,则入队的元素先存在stack1中,当stack2中为空时,将stack1中的所有元素push进stack2中,即可解决该问题。最后两个操作较简单,不作过多阐述。

LeetCode225.用队列实现栈

用队列实现栈
与上题题目基本类似,只不过这次是使用队列来实现栈。在这里我同样使用连两个队列来完成栈的操作。这次的基本思路是,始终留一个队列为空,每次进栈的元素都push进空的队列,然后再将另一个队列的每一个元素进行出队操作,依次进入这个原本为空的队列,这样原来不为空的队列将会为空,空队列将存在元素,如此循环,用队列实现入栈出栈的操作。

public class MyStack {

    static Queue<Integer> queue1;
    static Queue<Integer> queue2;

    public MyStack(){
        queue1=new LinkedList<>();
        queue2=new LinkedList<>();
    }

    public static void push(int x){
        if (queue1.isEmpty()){
            queue1.offer(x);
            while (!queue2.isEmpty()){
                queue1.offer(queue2.poll());
            }
        } else if (queue2.isEmpty()) {
            queue2.offer(x);
            while (!queue1.isEmpty()){
                queue2.offer(queue1.poll());
            }
        }
    }

    public static int pop(){
        if(queue1.isEmpty()){
            return queue2.poll();
        }else {
            return queue1.poll();
        }
    }

    public static int top(){
        if(queue1.isEmpty()){
            return queue2.peek();
        }else {
            return queue1.peek();
        }
    }

    public static boolean empty(){
        if (queue1.isEmpty()&& queue2.isEmpty()){
            return true;
        }else {
            return false;
        }
    }
}

LeetCode20.有效的括号

有效的括号

这是一道非常经典的应用栈的题目,在第一次学数据结构的时候,就遇到了该问题,这道题第一次还是使用c语言完成的,这次就使用java来实现。

首先,题目明确说明,只出现(){}[]这六种字符,不会出现别的字符,那么如此我们可以只关注这六种字符,如果遇到左括号,我们可以将其存如栈,如果遇到右括号,栈顶元素出栈,判断两者是否匹配,如果匹配继续操作,如果不匹配则说明不是有效括号,返回错误信息即可。注意,如果碰到右括号,而栈内为空,出栈将会报错,所以在出栈之前,先判断是否为空,如果为空,则说明先出现右括号,没有左括号,不是有效括号,如果不为空,才进行出栈匹配的操作。最后,当字符串遍历完成后,如果栈内不为空,说明有多出来的左括号没有被匹配掉,也不是有效的括号。如果以上都正确,最后将说明这是一个有效括号,返回正确信息即可。注意,这里if条件判断较多,但是并不难思考,细心将每一种情况思考完成后,即可完成本题。

	public static boolean isValid(String s){
        Stack<Character> stack=new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i)=='['||s.charAt(i)=='('||s.charAt(i)=='{'){
                stack.push(s.charAt(i));
                continue;
            }
            if (s.charAt(i)==']') {
                if (stack.isEmpty()){
                    return false;
                }else {
                    if (stack.pop()!='['){
                        return false;
                    }
                }
            }
            if (s.charAt(i)=='}') {
                if (stack.isEmpty()){
                    return false;
                }else {
                    if (stack.pop()!='{'){
                        return false;
                    }
                }
            }
            if (s.charAt(i)==')') {
                if (stack.isEmpty()){
                    return false;
                }else {
                    if (stack.pop()!='('){
                        return false;
                    }
                }
            }
        }
        if (stack.isEmpty()){
            return true;
        }else {
            return false;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值