leetcode-括号的分数

132 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

题目描述

给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:

  • () 得 1 分。
  • AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。
  • (A) 得 2 * A 分,其中 A 是平衡括号字符串。  

示例 1:

输入: "()"
输出: 1

示例 2:

输入: "(())"
输出: 2

示例 3:

输入: "()()"
输出: 2

示例 4:

输入: "(()(()))"
输出: 6

提示:

  • S 是平衡括号字符串,且只含有 ( 和 ) 。
  • 2 <= S.length <= 50

思路

虽然看题目是括号配对类型的,就知道是使用栈来处理,不过本题还真有不少小技巧。比如,怎么在一个堆栈里面同时存下数字和'(',相邻的括号怎么累加。看了三叶姐的题解,发现还是挺巧妙的。栈中存整数,'('作为0,这样,在pop的时候,0可以有区分度,而且及时作为相邻的括号组进行累加,也不会影响最后的结果。在开始的时候,先在栈中压入0,代表空字符串括号的值,这样可以应对 '()'开头时,第1个右括号如果pop2次,出现栈中元素不足的问题。
解决了上面的问题,再来看整体过程是:定义1个栈,先压入0,然后遍历字符串,遇到左括号,就压入0,遇到右括号,就从栈中弹出,这时有2种情况

  • 弹出的是0,说明上一个是左括号,即'()'的类型,值为1
  • 弹出的不是0,说明上一个是数字,即'(A)'的类型,值为2*A

这2种情况可以统一成 max(2*A, 1),注意要把再前1个元素作为相邻值弹出相加,由于'('作为0,所以即使遇到了,也不会影响结果。

Java版本代码

class Solution {
    public int scoreOfParentheses(String s) {
        Stack<Integer> stack = new Stack<>();
       stack.push(0);
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '(') {
                stack.push(0);
            } else {
                int pre = stack.pop();
                int prepre = stack.pop();
                stack.push(prepre + Integer.max(2 * pre, 1));
            }
        }
        return stack.peek();
    }
}