栈操作首篇

文章介绍了栈的基本概念和在Java中的应用,通过ArrayDeque实现有效括号的验证算法,以及设计一个支持常数时间检索最小元素的MinStack类。
摘要由CSDN通过智能技术生成

        栈(stack),它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。上面是百度百科给出栈的定义。个人认为其实不一定非得是表尾进行插入删除,也可以是表头进行插入删除。栈的特点先进先出。这里分享两道和栈有关的例题。在Java中ArrayDeque类中的pop()和push()就可以实现压栈和出栈操作,peek()方法可以查看当前栈顶元素。

有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
3.每个右括号都有一个对应的相同类型的左括号。

示例 1:
    输入:s = “()”
    输出:true
示例 2:
    输入:s = “()[]{}”
    输出:true
示例 3:
    输入:s = “(]”
    输出:false

class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack = new ArrayDeque<>();
        for(int i = 0;i < s.length();i++){
            if(s.charAt(i) == '('){
                stack.push(')');
            }else if(s.charAt(i) == '{'){
                stack.push('}');
            }else if(s.charAt(i) == '['){
                stack.push(']');
            }else if(stack.isEmpty() || stack.peek() != s.charAt(i)){
                return false;
            }else{
                stack.pop();
            }
        }
        return stack.isEmpty();
    }
}

        基本思路就是每次遇到左括号(‘(’,‘[’,‘{’),将其对应的右括号(‘)’,‘]’,‘}’)压入栈中。当遇到右括号时,判断栈顶元素是否与当前括号一致,不一致返回false,一致则将栈顶右括号弹出,继续遍历下一个符号。
        以"{(())}[]“为例子,说明上述代码执行的过程。首先遇到’{',将”}“压入栈中,此时栈中元素为[”}“],之后遇到’(',将”)“压入栈中,此时栈中元素为[”)“, “}”],之后遇到’(',将”)“压入栈中,此时栈中元素为[ “)”, “)”, “}”],之后遇到’)',栈顶元素为”)“,相等,将栈顶元素弹出,此时栈中元素为[”)“, “}”],之后遇到’)',栈顶元素为”)“,相等,将栈顶元素弹出,此时栈中元素为[”}“],之后遇到’}',栈顶元素为”}“,相等,将栈顶元素弹出,此时栈中元素为[],之后遇到’[',将”]“压入栈中,此时栈中元素为[”]“],之后遇到’]',栈顶元素为”]“,相等,将栈顶元素弹出,此时栈中元素为[]。while循环结束,返回stack.isEmpty(),栈为空,返回true。
        最后为什么要返回stack.isEmpty()作为最终答案,而不是直接返回true。举一个例子就很好说明白,比如”{()()“这个例子,整个while循环过程中,左括号和右括号的样式都是匹配的,如果在while循环最后直接返回true,显然不符合答案预期,而while循环结束,最后stack中会剩下[”}“],说明”}"没有匹配的右括号,所以可以根据stack是否为空返回最终的正确答案。

最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
1.MinStack() 初始化堆栈对象。
2.void push(int val) 将元素val推入堆栈。
3.void pop() 删除堆栈顶部的元素。
4.int top() 获取堆栈顶部的元素。
5.int getMin() 获取堆栈中的最小元素。

class MinStack {
    Deque<Integer> stack;
    Deque<Integer> helper;

    public MinStack() {
        stack = new ArrayDeque<>();
        helper = new ArrayDeque<>();
    }
    
    public void push(int val) {
        stack.push(val);
        if(helper.isEmpty() || helper.peek() > val){
            helper.push(val);
        }else{
            helper.push(helper.peek());
        }
    }
    
    public void pop() {
        stack.pop();
        helper.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return helper.peek();
    }
}

        这题要求的栈和普通的栈的区别就是可以通过getMin方法得到栈中的最小元素。这里可以通过一个辅助栈来维护栈中的最小元素。
        以[-2,-3,4,-1,-5]为例子,说明如何通过一个辅助栈维护栈中的最小元素。首先定义一个栈stack和辅助栈helper,并在MinStack类的构造方法中创建了两个栈的实例,之后来看push方法,关键就是push方法,首先压入-2,这个元素,stack直接压入-2,而helper辅助栈则需要判断栈是否为空,如果为空,直接压入,显然helper为空,直接将-2压入栈中。此时stack为[-2],helper[-2]。之后是-3,stack直接压入-3,而对于helper,此时已不为空,需要比较压入栈的元素-3和栈顶元素的大小,将更小的加入栈中,-3显然小于-2,则将-3压入栈中。此时stack为[-3, -2],helper[-3, -2]。之后是4,stack直接压入4,而helper需要比较栈顶元素和当前元素的大小4大于-3,继续将-3加入栈中。 此时stack为[4,-3, -2],helper[-3, -3, -2]。之后是-1,stack直接压入-1,而helper需要比较栈顶元素和当前元素的大小-1大于-3,继续将-3加入栈中。 此时stack为[-1, 4, -3, -2],helper[-3, -3, -3, -2]。之后是-5,stack直接压入-5,而helper需要比较栈顶元素和当前元素的大小-5小于-3,将-5加入栈中。 此时stack为[-5, -1, 4, -3, -2],helper[-5, -3, -3, -3, -2]。
        显然如果需要获取栈中最小元素,直接返回helper栈顶元素即可。注意helper可以获取任意时刻栈的最小值,如压入-2后,栈中最小元素为-2,也是helper栈顶元素,压入4后,栈中最小元素为-3,也是helper栈顶元素,压入-5后,栈中最小元素为-5,也是helper栈顶元素。stack和helper的数量一定是相等,并一一对应的,对stack做出栈操作,也需要对helper做出栈操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值