持续创作,加速成长!这是我参与「掘金日新计划 · 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();
}
}