栈和队列常考笔试题(一)

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

有效字符串需满足:
1、左括号必须用相同类型的右括号闭合。
2、左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

思路:
我们可以使用栈来判断字符串是否有效。
先定义一个栈,从所输入的第一个字符串开始判断,如果遇到左括号,全部入栈,而如果遇到了右括号,首先判断当前栈是否为空。
如果栈为空的时候遇到了右括号,说明不匹配;如果栈不为空遇到了右括号,那么首先拿出栈顶元素和这个右括号进行匹配,如果不是同一对括号,就比如说“(”遇到了“]”,很明显这也是不匹配的。就这样一直判断,所有字符串判断完毕,而且栈也为空了,说明就是这串字符串就是匹配的。
看代码:

public boolean isValid(String s) {
        Stack<Character> stack = new Stack<Character>();

        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            switch (ch) {
                case '(':
                case '[':
                case '{':
                    stack.push(ch);
                    break;
                case ')':
                case ']':
                case '}': {
                    if (stack.isEmpty()) {
                        return false;
                    }

                    char left = stack.pop();
                    if (!((left == '(' && ch == ')') || (left == '[' && ch == ']') || (left == '{' && ch == '}'))) {
                        return false;
                    }
                    break;
                }
                default:
                    break;
            }
        }
        if (stack.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }

2、使用栈实现队列

具体操作:
push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空

思路:
push操作很简单,将一个元素放入队列的尾部就是进行普通的入栈操作。
pop操作相对来说麻烦一点点,从队列的首部移除元素,我们可以定义两个栈来实现,一个in栈用来保存所有入栈的数据,一个out栈用来保存所有出栈出掉的数据。如果out栈为空,先从in栈出掉一个数据,再把出掉的这个数据进行入栈操作放到out栈中,这样一来,我们再从out栈出数据就相当于实现了从队列的首部移除数据。
在这里插入图片描述
peek操作和上面说过的pop操作基本上是一样的,只是peek操作不用出掉数据,只是查看out栈的栈顶元素,这个就是队列首部的元素。
empty操作判断队列是否为空,这需要in栈和out栈同时为空,否则就不能说明队列是空的。
具体代码如下:

class MyQueue {

        Stack<Integer> in;
        Stack<Integer> out;

        /**
         * Initialize your data structure here.
         */
        public MyQueue() {
            in = new Stack<Integer>();
            out = new Stack<Integer>();
        }

        /**
         * Push element x to the back of queue.
         */
        public void push(int x) {
            in.push(x);
        }

        /**
         * Removes the element from in front of queue and returns that element.
         */
        public int pop() {
            if (out.isEmpty()) {
                while (!in.isEmpty()) {
                    int v = in.pop();
                    out.push(v);
                }
            }
            int v = out.pop();
            return v;
        }

        /**
         * Get the front element.
         */
        public int peek() {
            if (out.isEmpty()) {
                while (!in.isEmpty()) {
                    int v = in.pop();
                    out.push(v);
                }
            }
            int v = out.peek();
            return v;
        }

        /**
         * Returns whether the queue is empty.
         */
        public boolean empty() {
            return in.isEmpty() && out.isEmpty();
        }
    }

3、实现一个最小栈

push(x) – 将元素 x 推入栈中。
pop() – 删除栈顶的元素。
top() – 获取栈顶元素。
getMin() – 检索栈中的最小元素。

思路:
实现一个最小栈是典型的以空间换时间问题。
我们需要定义两个栈,一个是normal栈,正常保存数据,一个min栈,用来保存当前栈中最小的数据。
往normal栈中放数据的同时,需要判断当前栈中最小的数据。第一次插入数据的时候,这个数据就是最小值,直接放入min栈。之后每一次都需要进行判断,如果min栈中栈顶元素比新插入的这个数据大,那么说明新插入的这个数据是最小值,把这个数据插入到min栈中,否则的话,将min栈的栈顶元素重新放入min栈中,代表当前栈中最小值依然是这个数据。
其它三个操作比较简单,代码直接就能看懂,注意删除元素的时候,两个栈的栈顶元素都要删除。
在这里插入图片描述
具体代码如下:

class MinStack {

        Stack<Integer> min;
        Stack<Integer> normal;

        /** initialize your data structure here. */
        public MinStack() {
            this.min = new Stack<Integer>();
            this.normal = new Stack<Integer>();
        }

        public void push(int x) {
            this.normal.push(x);
            if (this.min.isEmpty() || this.min.peek()>=x){
                this.min.push(x);
            }else {
                this.min.push(this.min.peek());
            }
        }

        public void pop() {
            this.normal.pop();
            this.min.pop();
        }

        public int top() {
            return this.normal.peek();
        }

        public int getMin() {
            return this.min.peek();
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值