题目描述
给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:
( ) 得 1 分。 AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。
(A) 得 2 * A 分,其中 A 是平衡括号字符串。
官方三解代码及相应注释
解法一:分治
class Solution {
public:
int scoreOfParentheses(string s) {
if (s.size() == 2) { //如果长度为2,也就是"()",直接返回1,同时也是触底条件
return 1;
}
int bal = 0, n = s.size(), len;
for (int i = 0; i < n; i++) {
bal += (s[i] == '(' ? 1 : -1);
if (bal == 0) {
len = i + 1;
break;
}
}
if (len == n) { //对应整个字符串为(A)的情况,这时删除两端的两个括号对内部进行处理
return 2 * scoreOfParentheses(s.substr(1, n - 2));
} else { //对应整个字符串为(A)(B)的情况,计算(A)+(B)
return scoreOfParentheses(s.substr(0, len)) + scoreOfParentheses(s.substr(len, n - len));
}
}
};
解法二:栈(括号匹配)
class Solution {
public:
int scoreOfParentheses(string s) {
stack<int> st;
st.push(0);//最终所求整体的值,开始为0
for (auto c : s) {
if (c == '(') {//新开始一个括号,压入一个0
st.push(0);
} else {//结束一个括号,第一次top()用来弹出当前结束的这个括号的值,第二次top()用来求(A)的值。第一次弹出的是(A)中的A对应的值,第二次top是求(A)的值
int v = st.top();
st.pop();
st.top() += max(2 * v, 1);
}
}
return st.top();
}
};
解法三:计算最终分数和
不加注释了,主要是思想,可以理解为扒洋葱皮使其最终成为AB 得 A + B 分的形式:
1. ( ( ) ( ( ) ) ) = ( ) + ( ( ) )
2.( ( ) ( ) ( ( ( ) ( ) ) ) ) = () + () + ( ( ()+() ) )
= ()+()+( ( ( ) ) )+( ( ( ) ) )
class Solution {
public:
int scoreOfParentheses(string s) {
int bal = 0, n = s.size(), res = 0;
for (int i = 0; i < n; i++) {
bal += (s[i] == '(' ? 1 : -1);
if (s[i] == ')' && s[i - 1] == '(') {
res += 1 << bal;
}
}
return res;
}
};