题目描述:
给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:
● () 得 1 分。
● AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。
● (A) 得 2 * A 分,其中 A 是平衡括号字符串。
示例 1:
输入: "()"
输出: 1
示例 2:
输入: "(())"
输出: 2
示例 3:
输入: "()()"
输出: 2
示例 4:
输入: "(()(()))"
输出: 6
提示:
S 是平衡括号字符串,且只含有 ( 和 ) 。
2 <= S.length <= 50
思路:
这是一道很有意思的题目,首先理解一下题目意思,AB是指"()()“型,就是两个整体的数值相加,(A)是指”(())"型,也就是嵌套型
有好几种思路,可以利用栈,也可以直接从头遍历并计算
1、第一种方法:利用栈
初始化一个整型栈,然后从头开始遍历字符串,如果是’(’,则把数字0压栈,如果是’)’,此时会有两种情况:使用一个变量top记录栈顶元素,如果栈顶是0,说明上一个字符为’(’,此时的括号为最内层括号,将top赋值为1;如果不为0,则之前已经有括号出现过了,就是上面所说的嵌套型,将top*=2。再将栈顶取出,此时若栈空,说明遍历结束,如果栈不为空,则再将top+=栈顶元素,因为此时是"()()"型,再将top压栈继续遍历字符串
代码:
class Solution {
public int scoreOfParentheses(String s) {
int ans = 0;
Stack<Integer> stack = new Stack();
for(int i = 0;i < s.length();i++){
char c = s.charAt(i);
if(c=='('){
stack.push(0);
}else{
int top = stack.peek();
if(stack.peek()==0){
top = 1;
}else{
top *= 2;
}
stack.pop();
if(!stack.isEmpty()){
top += stack.pop();
stack.push(top);
}else{
ans += top;
}
}
}
return ans;
}
}
官方题解里面有个简单的方法,可以减少很多判断:
public int scoreOfParentheses(String S) {
Stack<Integer> stack = new Stack();
stack.push(0); // The score of the current frame
for (char c: S.toCharArray()) {
if (c == '(')
stack.push(0);
else {
int v = stack.pop();
int w = stack.pop();
stack.push(w + Math.max(2 * v, 1));
}
}
return stack.pop();
}
2、第二种方法:统计核心的数目
这种方法不需要使用栈,可以减少空间使用
我们可以把问题简单化一下,因为只有"()"是会产生具体的分数,其他的都只是将分数×2或者分数累加,所以,只需要算出每一个()对应的深度depth,然后累加2^depth就是答案。
代码:
也是官方题解:
class Solution {
public int scoreOfParentheses(String s) {
int ans = 0, depth = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
depth++;
} else {
depth--;
if (s.charAt(i - 1) == '(') {
ans += Math.pow(2, depth);
}
}
}
return ans;
}
}