刷题 - 栈题

目录

1.有效的括号

​编辑

题解:使用栈来解决 

2.逆波兰表达式求值

什么是逆波兰表达式

 题解:使用栈来解决

 3.栈的压入、弹出序列

题解:使用栈来解决

 4.最小栈

题解1:额外创建一个栈来放入最小元素(最小栈和数据站同步)

 题解2:额外创建一个最小栈,数据栈和最小栈不同步


1.有效的括号

题目链接:

https://leetcode.cn/problems/valid-parentheses/https://leetcode.cn/problems/valid-parentheses/

✍有效字符: ( [ { } ] )        ( { [  ] } )

✍无效字符:{ [ ( ] ) }        ( { [ } ) 

题解:使用栈来解决 

有效字符的判断逻辑:

首先创建一个栈,首先遍历字符串,如何是左括号就将他转换为对应的右括号放入栈中,如果是右括号就和栈中已经放入的符号比较是否相同,相同就出栈,直到遍历完查看栈是否为空。

🤨特殊情况:

1.如果字符串开始就为null,我们需要在开头处判断是否为空;

2.如果字符串的右括号过多 ( ( ) ) ) ),栈中的左括号出栈出完了,此时我们需要判断栈是否为空;

3.如果左括号过多,( ( ( ( ) ) ) ,会发生在遍历完毕后导致栈中还留有元素,此时需要在遍历完成后判断栈是否为空;

代码:

class Solution {
    public boolean isValid(String s) {
        if(s.isEmpty()) {
            return false;
        }
        Stack<Character> stack = new Stack();//存放左括号
        for(int i = 0;i < s.length();i++) {
            Character c = s.charAt(i);
            //是左括号就将他转换为他的反括号放入栈中
            if(c == '{') {
                stack.push('}');
            }else if(c == '(') {
                stack.push(')');
            }else if(c == '['){
                stack.push(']');
            }else if(stack.empty() || stack.peek() != c) {
                return false;
            }else {
                stack.pop();
            }
        }
        if(stack.empty()) {
            return true;
        }
        return false;
    }
}

2.逆波兰表达式求值

题目链接:力扣https://leetcode.cn/problems/evaluate-reverse-polish-notation/

什么是逆波兰表达式

首先解释一下什么是逆波兰表达式,也叫后缀表达式

正常的算式(中缀表达式):1 + 2 * 3 / 5

逆波兰表达式(后缀表达式):1 23 * 5 / +

过程解释:

首先将我们的算式加长括号来表示运算符的优先顺序,因为电脑不知道哪个运算符先算:

1 + ( (2 * 3)/ 5) , 然后我们一步一步拆分括号,根据转换公式 a + b = ab+ 来画图演示一下

 题解:使用栈来解决

根据后缀表达式的特性正好符合我们的栈

🧐思路:

将表达式(数组)遍历一遍,如果是数字就将他放进栈中,如果是运算符就将栈中俩个数字拿出来和我们的运算符计算求值,然后将值放入栈中继续遍历。

画图演示:

🎃注意事项: 遇到运算符时出栈俩个元素进行计算时,注意我们的除法运算符的俩变数字不一样那么算式的值也是不一的,例如2 + 3 = 5 相等于 3 + 2 = 5,但是除法 3 / 2 和 2 / 3 这俩个式子的结果是不一样的,所以我们要将先出栈的元素放置运算符的右边,后出栈的元素放置于运算符的左方即可。

代码:

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> s = new Stack();
        int sum = 0;
        int x = 0;
        int y = 0;
        for(int i = 0;i < tokens.length;i++) {
            String c = tokens[i];
            if(c.equals("+")) {//为运算符时
                y = s.pop();
                x = s.pop();
                sum = x + y;
                s.push(sum);
            }else if(c.equals("-")) {
                y = s.pop();
                x = s.pop();
                sum = x - y;
                s.push(sum);
            }else if(c.equals("*")) {
                y = s.pop();
                x = s.pop();
                sum = x * y;
                s.push(sum);
            }else if(c.equals("/")) {
                y = s.pop();
                x = s.pop();
                sum = x / y;
                s.push(sum);
            }else{//为数字时
            Integer a = Integer.parseInt(tokens[i]);//parseInt可以将String类字符转换为int型
            s.push(a);
            }
        }
        return s.pop();
    }
}

 3.栈的压入、弹出序列

题目链接:

栈的压入、弹出序列_牛客题霸_牛客网【牛客题霸】收集各企业高频校招笔面试题目,配有官方题解,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的技术能力https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId=13&&tqId=11174&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking题目描述:

题解:使用栈来解决

🧐思路:

首先创建一个栈,遍历我们的压入序列,将压入序列的元素放入栈中,每次遍历压入栈中的元素和我们的弹出序列相比较,如果相等,栈执行出栈操作一次,弹出序列下标往后走一步,直到遍历完我们的压入序列,最后判断栈是否为空即可。

画图描述一下思路:

代码:

import java.util.Stack;

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        int index = 0;
        Stack<Integer> stack = new Stack<>();
        for(int i = 0;i < pushA.length;i++) {
            stack.push(pushA[i]);
            while(!stack.empty() && stack.peek() == popA[index]) {
                stack.pop();
                index++;
            }
        }
        return stack.empty();
    }
}

 4.最小栈

题目链接:

力扣https://leetcode.cn/problems/min-stack/description/题目描述:

题解1:额外创建一个栈来放入最小元素(最小栈和数据站同步)

🧐思路:

除了我们正常用来出栈、入栈等一系列栈的基本操作使用的的 栈 除外,我们额外创建一个最小栈,用来存放最小的元素,使我们的 getMin 可以获取到当前栈中的最小元素,

每次入栈时,不仅数据栈也要入栈,还要判断入栈的 val 值如果小于最小栈的栈顶元素我们我们也要将val值入栈到最小栈中,如果大于我们直接将最小栈的栈元素再入一份到栈顶就行了,当然前提是需要判断当前最小栈内是否为空。

出栈时,数据站和最小栈都需要出栈一个元素。

获取栈顶元素时获取 数据栈 的栈顶元素就行了

获取当前栈的最小元素时之间获取 最小栈 的栈顶元素即可


根据实例进行操作

 实例中:

① 调用 MinStack() 构造方法初始化堆栈对象

② 然后 push() 入栈三个元素

③ getMin() 获取最小元素

④ pop() 出栈一个元素

⑤ top() 获取栈顶元素

⑥ getMin() 获取最小元素

 题解2:额外创建一个最小栈,数据栈和最小栈不同步

🧐思路:

和题解1大致一样,区别在于栈的同步,当前我们入栈时,最小栈并不需要每次都入栈一个元素,只有在 val <= 最小栈时才进行入栈。

出栈时,最小栈的栈顶元素等于数据栈的栈顶元素时 (即数据栈需要出栈的元素) ,最小栈才进行出栈。

获取栈顶元素为数据栈顶元素

获取当前栈最元素为最小栈 栈顶元素

画图描述:

有错误的地方麻烦指出🤜🤛

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值