代码随想录第十天| leecode 20,1047,150

本文介绍了如何使用栈数据结构解决LeetCode中的三个问题:验证有效括号、删除字符串中相邻的重复字符以及计算逆波兰式。通过栈的先进后出特性,作者展示了高效的解题思路和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章:代码随想录

总结:栈在连续,相邻的位置做匹配/消除/运算的场景很适用.

leecode 20 有效括号

思路:

做这道题之前有一些特性需要明白,括号是符合先进后出的原理的,也就是后进先出. 比如({[]}),先进入的(肯定是包含在最外面的,最后进入的左[括号一定是最先出现右括号的,所以是先进后出。 那么很显然就可以用栈来实现这个问题。

public boolean isValid(String s) {
        //如果s的长度为奇数,那肯定是不符合要求的,因为括号成双成对出现
        if(s.length()%2!=0){return false;}
        Stack<Character> rightParentheses=new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char ch=s.charAt(i);
            //遇到左括号,压入右括号
            if(ch=='('){rightParentheses.push(')');}
            else if (ch=='{'){rightParentheses.push('}');}
            else if(ch=='['){rightParentheses.push(']');}
            //走到这里说明输入的是右括号,如果栈空了说明存在右括号多余的情况。如果不匹配则证明发生了左右括号不匹配的情况,都直接返回false.
            else if(rightParentheses.empty() || ch!=rightParentheses.peek()){return false;}
            //相同情况
            else {rightParentheses.pop();}
        }
        //结束时要判断是否全部弹出,因为如果左括号或者又括号多余上面的循环是无法返回false的.
        return rightParentheses.empty();
    }

leecode 1047 删除字符串中相邻的重复项

思路:和找有效括号的思路是一样的,因为找有效括号有一部分逻辑也是相当于消除相邻的重复括号,所以这道题的代码会更精简。 用栈是显而易见的,那么其实这里可以用一个字符串模拟栈的行为,这样就不用最后再通过栈里的元素来转换成字符串。 //然后我们还可以将这个字符串的头尾转换,这样最后也不用倒序输出。

代码:

public String removeDuplicates(String s) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            //不相等就push
            if (result.isEmpty() || s.charAt(i) != result.charAt(result.length() - 1)) {
                result.append(s.charAt(i));
            }else {
            //元素相等的情况就移除栈内元素.(pop)
                result.deleteCharAt(result.length()-1);
            }
        }
        return result.toString();

    }


    //操作更快的charArray方式
    public String removeDuplicatesCharArray(String S) {
        char[] s = S.toCharArray();
        int top = -1;
        for (int i = 0; i < S.length(); i++) {
            if (top == -1 || s[top] != s[i]) {
                s[++top] = s[i];
            } else {
                top--;
            }
        }
        return String.valueOf(s, 0, top + 1);
    }

leecode 150 逆波兰式

思路:

遇到元素压入栈中,算术表达式就将栈的头两个元素拿出来计算再把计算完的值压入栈中。 //要注意顺序式是头元素中的后一个与第一个运算,比如是后一个除以第一个,减去第一个等等.

代码:

 public int evalRPN(String[] tokens) {
        Stack<Integer> result=new Stack<>();
        for (String s:tokens) {
            if(s.equals("+")){
                result.push(result.pop()+result.pop());
            }else if(s.equals("-")){
                result.push(-result.pop()+result.pop());

            }else if(s.equals("*")){
                result.push(result.pop()*result.pop());
            }else if(s.equals("/")){
                int result1=result.pop();
                int result2=result.pop();
                result.push(result2/result1);
            }else {
                result.push(Integer.valueOf(s));
            }

        }
        return result.pop();

    }

    //数组模拟栈的方法

    public int evalRPNArray(String[] tokens) {
        int n = tokens.length;
        int[] stack = new int[(n + 1) / 2];
        int index = -1;
        for (int i = 0; i < n; i++) {
            String token = tokens[i];
            switch (token) {
                case "+":
                    index--;
                    stack[index] += stack[index + 1];
                    break;
                case "-":
                    index--;
                    stack[index] -= stack[index + 1];
                    break;
                case "*":
                    index--;
                    stack[index] *= stack[index + 1];
                    break;
                case "/":
                    index--;
                    stack[index] /= stack[index + 1];
                    break;
                default:
                    index++;
                    stack[index] = Integer.parseInt(token);
            }
        }
        return stack[index];
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值