代码随想录Day11(20.有效的括号&1047.删除字符串中的所有相邻重复项&150.逆波兰表达式求值)

文章讲述了如何使用栈和哈希表判断字符串中的有效括号序列,以及如何通过栈处理逆波兰表达式进行计算。涉及到了栈的入栈和出栈操作以及哈希表的数据存储和查找。
摘要由CSDN通过智能技术生成

代码随想录Day11

20.有效的括号

  • 初始化一个栈 stack 和一个哈希表 map。栈用于存储左括号,哈希表用于存储括号及其对应的标识。

  • 填充哈希表 map,将左括号和右括号映射为不同的整数。这里将左括号映射为 1、2、3,而将对应的右括号映射为 4、5、6。

  • 遍历字符串 s 中的每个字符。

  • 对于每个字符 c,检查它是否在哈希表 map 中。如果不在,则将其视为无效字符,将变量 a 设置为 false 并退出循环。

  • 如果 c 是左括号(即 map.getOrDefault(c, -1) 的值在 1 到 3 之间),则将其压入栈中。

  • 如果 c 是右括号,则检查栈是否为空以及栈顶的左括号是否与当前右括号匹配。匹配的条件是 map.get(stack.peek()) ==
    flag - 3。如果匹配,则弹出栈顶的左括号;如果不匹配或栈为空,则将变量 a 设置为 false 并退出循环。

  • 遍历完字符串 s 后,检查栈是否为空。如果栈不为空,则说明还有未匹配的左括号,将变量 a 设置为 false。

  • 返回变量 a 的值。如果 a 为 true,则括号序列有效;如果为 false,则括号序列无效。

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack  = new Stack<>();
        Map<Character,Integer> map = new HashMap<Character,Integer>();
        boolean a = true;
            //给map中填入数据(key,value)
            map.put('(', 1);  
            map.put('[', 2);  
            map.put('{', 3);  
            map.put(')', 4);  
            map.put(']', 5);  
            map.put('}', 6);  
            //根据c获取对应的value值,如果c不在map中返回-1
            for(char c : s.toCharArray()){
                //根据
                Integer flag = map.getOrDefault(c,-1);
                //左括号入栈
                if(flag >= 1 && flag <=3){
                    stack.push(c);
                }
                //右括号,栈顶是对应左括号时直接出栈
                else if (!stack.isEmpty() && map.get(stack.peek()) == flag - 3) {  
                stack.pop(); 
                }
                //右括号,但栈为空or栈顶不是对应左括号,退出循环
                else{
                    a = false;
                    break;
                }
            }

            //栈不为空,还有左括号
            if(!stack.isEmpty()){
                a = false;
            }

            return a;
    }
}

1047.删除字符串中的所有相邻重复项

该题要求去除字符串中的相邻重复字符。具体做法是利用栈的特性,在遍历字符串时,根据栈顶元素与当前字符的对比,决定是否将当前字符入栈。

  • 首先,我们创建一个栈 stack 来存储字符。然后,遍历字符串 s 中的每个字符 c。

  • 对于每个字符 c,我们检查栈是否为空或者栈顶元素是否与 c 不同。如果满足这两个条件之一,说明 c 不是与栈顶相邻的重复字符,因此我们将c 入栈。

  • 如果栈不为空且栈顶元素与 c 相同,说明 c 是与栈顶相邻的重复字符,我们执行出栈操作,即 stack.pop(),以去除这个重复字符。

  • 遍历完整个字符串后,栈中剩余的字符就是去除相邻重复字符后的结果。然而,由于栈是后进先出的数据结构,我们还需要将栈中的字符按照正确的顺序组合成字符串。

  • 为此,我们使用 StringBuilder 来构建结果字符串。通过循环,将栈中的字符依次弹出并添加到 StringBuilder
    中。最后,由于栈是反向存储的,我们需要调用 StringBuilder 的 reverse() 方法来反转字符串,得到最终的结果。

class Solution {
    public String removeDuplicates(String s) {
        Stack<Character> stack  = new Stack<>();
        for(char c : s.toCharArray()){
            //如果栈为空或者与栈顶元素不相同,入栈
            if(stack.isEmpty() || c != stack.peek()){
                stack.push(c);
            }else{
                stack.pop();    //与栈顶相同说明为相邻重复元素
            }
        }

         // 使用StringBuilder来构建结果字符串  
        StringBuilder stringBuilder = new StringBuilder();  
        // 将栈中的元素依次添加到StringBuilder中  
        while (!stack.isEmpty()) {  
            stringBuilder.append(stack.pop());  
        }  
  
        // StringBuilder已经以正确的顺序包含所有字符,不需要反转  
        return stringBuilder.reverse().toString(); 

    }
}

150.逆波兰表达式求值

对逆波兰表达式求值的过程是:

如果遇到数字就进栈;
如果遇到操作符,就从栈顶弹出两个数字分别为栈顶(a)、栈中的第二个元素(b);
计算 b 运算符 a
  • 首先,我们创建一个整数栈 stack,用于存放数字和中间结果。然后,遍历输入的逆波兰表达式字符串数组 tokens。
  • 对于数组中的每个元素,我们进行如下判断:
  • 如果元素是运算符(即 +、-、* 或 /),我们从栈中弹出两个数字。由于栈是后进先出的数据结构,弹出的第一个数字是栈顶元素,记作a,弹出的第二个数字是栈中原本位于 a 下方的元素,记作 b。接着,根据运算符进行相应的运算,并将运算结果推回栈中。
  • 如果元素是数字,我们直接将其转换为整数,并推入栈中。
  • 遍历完所有元素后,栈中应该只剩下一个元素,这个元素即为逆波兰表达式的计算结果。我们将其从栈中弹出并返回。
class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for(String s : tokens){
            //如果是运算符,拿出栈顶的两个元素,然后将二者计算结果在放入栈中
            if("+-*/".contains(s)){
                int a = stack.pop();
                int b = stack.pop();
                switch(s){
                    case"+":
                        stack.push(b + a);
                        break;

                    case"-":
                        stack.push(b - a);
                        break; 

                    case"*":
                        stack.push(b * a);
                        break;

                    case"/":
                        stack.push(b / a);
                        break;
                }
            }else{
                //数字直接进栈
                stack.push(Integer.parseInt(s));
            }  
        }
        return stack.pop();
    }    
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值