题目
我的思路 错误的
先想到用栈,但是,没想通,换成了计数…
记录遇到的左括号的数量,如果遇到的左括号的数量不为零,继续匹配右括号的数量【右括号的数量只可能小于等于左括号的数量】,按照右括号的数量开计算【比如先遇到3个左括号,再遇到2个右括号,则说明有两个括号嵌套,需要乘以2】,按照左括号、右括号匹配,最后还剩下右括号,需要乘以相应的倍数,不过,下面的代码没办法判断,最后剩下的右括号与之匹配的左括号是在什么地方…
默认,括号扩在最外层
class Solution {
public int scoreOfParentheses(String s) {
int len = s.length();
int left;
int i = 0;
int res = 0;
int temp;
while (i < len) {
left = 0;
while (i < len && s.charAt(i) == '(') {
i++;
left++;
}
if (left != 0) {
temp = left;
while (temp > 0 && s.charAt(i) == ')') {
temp--;
i++;
}
if (temp == 0) {
res += Math.pow(2, left - 1);
} else {
res += Math.pow(2, left - temp - 1);
}
} else {
break;
}
}
res *= Math.pow(2, len - i);
return res;
}
}
官方思路
方案一 分治
根据题意,一个平衡括号字符串s可以被分解为A+B或(A)的形式,因此我们可以对s进行分解,分而治之
如何判断s应该分解为A+B或(A)的哪一种呢?将左括号记为1,右括号记为-1
- 如果s的某个非空前缀对应的和bal=0,那么这个前缀就是一个平衡括号字符串
- 如果该前缀长度等于s的长度,那么s可以分解为(A)的形式
- 否则s可以分解为A+B的形式,其中A为该前缀。将s分解之后,我们递归地求解子问题,并且s的长度为2时,分数为1
class Solution {
public int scoreOfParentheses(String s) {
if (s.length() == 2) {
return 1;
}
int sum = 0;
int n = s.length();
int len = 0;
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '(') {
sum++;
} else {
sum--;
}
//s的某个非空前缀对应的和为0
if (sum == 0) {
len = i + 1;
break;
}
}
//如果该前缀长度等于s的长度,那么可分解为(A)
if (len == n) {
return 2 * scoreOfParentheses(s.substring(1, n - 1));
}
//如果前缀长度不等于s,那么可分解为A+B
return scoreOfParentheses(s.substring(0, len)) + scoreOfParentheses(s.substring(len, n));
}
}
方案二 栈(个人觉得比较难理解)
把平衡字符串s看作是一个空字符串加上s本身,并且定义空字符串的分数为0。使用栈stack记录平衡字符串的分数,在开始之前要压入分数为0的空字符串
在遍历字符串s的过程中:
- 遇到左括号,需要计算左括号内部的子平衡括号字符串A的分数,我们也需要先压入分数0,表示A前面空字符串的分数
- 遇到右括号,说明该右括号内部的子平衡括号字符串A的分数已经计算出来了,我们将它弹出栈,并保存到变量v中。如果v=0,那么说明平衡括号字符串A是空串,(A)的分数为1,否则(A)的分数为2v,然后将(A)的分数加到栈顶元素上
遍历结束后,栈顶元素保存的就是s的分数
import java.util.Stack;
class Solution {
public int scoreOfParentheses(String s) {
Stack<Integer> st = new Stack<>();
st.push(0);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
st.push(0);
} else {
int v = st.pop();
int top = st.pop() + Math.max(2 * v, 1);
st.push(top);
}
}
return st.peek();
}
}
方案三 计算最终得分(推荐)
根据题意,s的分数与1分()有关,对于每个(),它的最终得分与它所处的深度有关,如果深度为bal,那么它的最终分数为bal,我们统计所有分()的最终分数即可
class Solution {
public int scoreOfParentheses(String s) {
int bal = 0;
int n = s.length();
int res = 0;
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '(') {
bal++;
} else {
bal--;
}
if (s.charAt(i) == ')' && s.charAt(i - 1) == '(') {
res += (1 << bal);
}
}
return res;
}
}