给定一个平衡括号字符串 S
,按下述规则计算该字符串的分数:
()
得 1 分。AB
得A + B
分,其中 A 和 B 是平衡括号字符串。(A)
得2 * A
分,其中 A 是平衡括号字符串。
示例 1:
输入: "()" 输出: 1
示例 2:
输入: "(())" 输出: 2
示例 3:
输入: "()()" 输出: 2
示例 4:
输入: "(()(()))" 输出: 6
思路1:
分治法:
int scoreOfParentheses(string s)的返回值是当前字符串s的分数。
对字符串s进行分解,分而治之。base case是分解到只有“()”,此时返回分数1;
分解的过程中有两种情况,AB和(A),如何判断是这两种中的哪一个?可以从左向右遍历字符串s,将' ( '记为 1,' ) '记为 -1,记录它们的总和。如果遍历完所有的括号后,总和才为0,那么就是(A)形式的,返回值为2 * score(A) ;如果遍历了一部分总和就为0了,那么就是AB形式的,返回值为score(A)+score(B)。
class Solution {
public:
int scoreOfParentheses(string s) {
if(s=="()")//base case
return 1;
int sum=0;
int i=0;
for(i=0;i<s.size();i++)//遍历求和
{
if(s[i]=='(')
sum++;
else
sum--;
if(sum==0)//和为0时,退出循环
{
break;
}
}
if(i==s.size()-1)//情况:(A)
return 2*scoreOfParentheses(s.substr(1,s.size()-2));
else//情况:AB
return scoreOfParentheses(s.substr(0,i+1))+scoreOfParentheses(s.substr(i+1,s.size()-i-1));
}
};
思路2:
栈模拟【爪哇缪斯】图解LeetCode - 括号的分数 - 力扣(LeetCode)
注意ASCII码和数字之间的转换。。。
//栈模拟
class Solution {
public:
int scoreOfParentheses(string s) {
stack<int> st;
for(const char& c:s)
{
if(c=='(')//如果是 ( 就进栈
{
st.push('(');
}
else//如果是 )
{
int tp=st.top();
if(tp=='(')//如果栈顶元素是 ( ,那么左右括号匹配(),得1分
{
st.pop();
st.push(1+2000);
//将分数压入栈内,因为要和用ASCII码表示的'('、')'避开,
//防止压入栈内的结果与之撞车,所以给结果都加上2000的偏移
}
else//如果栈顶元素不是 ( ,是压入栈内的结果
{
int sum=0;
while(tp!='(')//连续出栈,直到栈顶元素为 (
{
sum+=tp-2000;//AB=A+B
st.pop();
tp=st.top();
}
st.pop();//栈顶元素 ( 和 遍历到的 )匹配(A)=2*A
st.push(2*sum+2000);
}
}
}
int res=0;
while(!st.empty())//栈内所有元素之和为总分
{
res+=st.top()-2000;
st.pop();
}
return res;
}
};