Hot100 栈

20. 有效的括号 - 力扣(LeetCode)

左括号入栈  右括号匹配上peek就出栈 不匹配报错 最后栈不为空报错

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

        for (char c : s.toCharArray()) {
            if (c == '(' || c == '{' || c == '[') {
                stack.push(c);
            } else if (c == ')' && (!stack.isEmpty() && stack.peek() == '(')) {
                stack.pop();
            } else if (c == '}' && (!stack.isEmpty() && stack.peek() == '{')) {
                stack.pop();
            } else if (c == ']' && (!stack.isEmpty() && stack.peek() == '[')) {
                stack.pop();
            } else {
                return false;
            }
        }
        //栈为空就对了
        return stack.isEmpty(); 
    }
}

c.equals('(')

  • 类型:这是一个对象方法的调用。

  • 比较方式equals 方法用于比较对象的内容。注意,equals 方法通常用于比较对象类型(如 StringInteger 等),而不是基本数据类型。

  • 适用场景:适用于对象的比较,通常用于 String 或其他对象类型。

  • 性能:由于涉及方法调用,性能可能稍低于 == 运算符。

    c == '('

  • 类型:这是一个基本数据类型的比较。

  • 比较方式:使用 == 运算符直接比较两个字符的值。

  • 适用场景:适用于基本数据类型(如 charint 等)的比较。

  • 性能:由于是直接比较基本数据类型的值,因此性能较高。

155. 最小栈 - 力扣(LeetCode) 

主栈是正常的操作,辅助栈用来维护最小的值

所以push和pop操作只需要关心辅助站是否需要更新栈顶元素即可。

class MinStack {
    private Stack<Integer> stack;
    private Stack<Integer> min_stack;   
    public MinStack() {
        stack=new Stack<>();
        min_stack=new Stack<>();
    }
    //push()方法:每当push()新值进来时,如果小于等于 min_stack栈顶值,则一起push()到min_stack,即更新了栈顶最小值;
    public void push(int val) {
        //if(stack==null)min_stack 是一个对象,永远不会为 null。
    // 正确的条件应该是 !min_stack.isEmpty()。
        if(min_stack.isEmpty()||val<min_stack.peek())
        {
            min_stack.push(val);//要考虑空的情况!!
        }
        stack.push(val);
    }
    
    public void pop() {
        // 如果主栈的栈顶元素等于辅助栈的栈顶元素,则辅助栈也需要弹出
         if(stack.pop().equals(min_stack.peek()))
            min_stack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return min_stack.peek();
    }
}

 394. 字符串解码 - 力扣(LeetCode)

法一:辅助栈法


本题难点在于括号内嵌套括号,需要从内向外生成与拼接字符串,这与栈的先入后出特性对应。

思路:

  1. 初始化

    • 使用 StringBuilder 存储当前解码的字符串。

    • 使用两个栈分别存储数字和字符串。

  2. 遍历输入字符串

    • 遇到 [:保存当前状态,重置 multires

    • 遇到 ]:从栈中恢复状态,重复当前字符串并拼接。

    • 遇到数字:更新 multi

    • 遇到字母:追加到当前字符串。

  3. 返回最终解码的字符串

算法流程:

构建辅助栈stack, 遍历字符串s中每个字符c;
当c为数字时,将数字字符转化为数字multi,用于后续倍数计算;
当c为字母时,在res尾部添加c;

当c为[时,将当前multi和res入栈,并分别置空置0:

  • 记录此[前的临时结果res至栈,用于发现对应]后的拼接操作;
  • 记录此[前的倍数multi至栈,用于发现对应]后,获取multi × [...]字符串。
  • 进入到新[后,res和multi重新记录。

当c为]时,stack出栈,拼接字符串res = last_res + cur_multi * res,其中:
last_res是上个[到当前[的字符串,例如"3[a2[c]]"中的a;
cur_multi是当前[到]内字符串的重复倍数,例如"3[a2[c]]"中的2。
返回字符串res。

class Solution {
    public String decodeString(String s) {
        StringBuilder res=new StringBuilder();
        int multi=0;
        LinkedList<Integer> stack_multi = new LinkedList<>();
        LinkedList<String> stack_res = new LinkedList<>();
        for(Character c : s.toCharArray()) {
            //当c为[时,将当前multi和res入栈,并分别置空置0
            if(c == '[') {
                //记录此[前的临时结果res至栈,用于发现对应]后的拼接操作;
                //记录此[前的倍数multi至栈,用于发现对应]后,获取multi × [...]字符串。
                stack_multi.addLast(multi);
                stack_res.addLast(res.toString());
                multi = 0;
                res = new StringBuilder();
            } else if(c == ']') {
                //要进行处理了!
                StringBuilder tmp = new StringBuilder();
                int cur_multi = stack_multi.removeLast();//取出我们要的乘数
                //此时res还指着]里面的的字符串
                for(int i = 0; i < cur_multi; i++) tmp.append(res);
                res = new StringBuilder(stack_res.removeLast() + tmp);
            } else if(c >= '0' && c <= '9') 
            {
                multi=multi*10+(c-'0');
                // multi = multi * 10 + Integer.parseInt(c + "");
            }
            else res.append(c);
}
        return res.toString();

    }
}

 739. 每日温度 - 力扣(LeetCode)

用栈来保存并更新曾经的温度索引,且栈顶永远是目前的最低温度

后面的气温比栈顶气温高->把能算的days[]都算出来,出栈,一直到这个气温比栈顶气温低

后面的气温比栈顶低->入栈

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        // 栈的性质是:栈顶的温度总是最低的。
        //后面的气温是非升即走(入栈)
        //栈里存的是索引
       int[] days=new int[temperatures.length];
        Deque<Integer> stack=new LinkedList<>();
        for(int i=0;i<temperatures.length;i++)
        {
            while(!stack.isEmpty()&&temperatures[i]>temperatures[stack.peek()])
            {
                //如果栈不为空且当前气温大于栈顶气温
                //更新栈顶那天对应的days数组
                days[stack.peek()]=i-stack.peek();
                //别忘了更新栈!
                stack.pop();
            }
            //此时要么栈为空要么stack中的气温全都大于当前气温 当前气温又变成了最小气温
            stack.push(i);
        }
        //最后一天的肯定无人更新 不用管了,,
        return days;
    }
}

单调栈
d84. 柱状图中最大的矩形 - 力扣(LeetCode)
 

 

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。


以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。


图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。


# 题目分析
柱子彼此相邻,宽度都为1,高度各不相同。对于当前考察的柱子来说,它所能勾勒出的矩形面积是由其左边柱子和右边柱子的高度共同决定的。

如果其左边柱子的高度大于等于当前柱子的高度,则可以向左侧扩张,直到左边柱子高度小于当前柱子高度或左边再无其它柱子;同样的,如果其右边柱子的高度大于等于当前柱子的高度,则可以向右侧扩张,直到右边柱子高度小于等于当前柱子高度或右边再无其它柱子。

这时,就可以计算出以当前柱子高度为高,左右柱子间距离为宽的矩形面积。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值