大佬,牛!!!
- 题目:给你一个字符串,里面是一个平衡的括号。这里的平衡的括号的意思就是能够配对成功。然后让你计算这个括号的得分,这里给了得分的规则,()是一分,然后()()表示左边的值+右边括号计算出来的值,(())表示里面括号的值*2。
- 我的思路:我想过递归,想过用栈,想过分治,但是动手写的时候,我写不动。最后直接放弃了。
- 大佬的思路——分治:首先说一下分治。思路就是每次找到第一个位置(这个位置肯定是左括号)与之对应的右括号,然后这一块我们进行一个计算。剩下的再进行一次计算。每次都这样进行下分。然后如果长度等于2表示左右括号,则直接返回1。然后就是剩下的两种了,如果这个右括号的位置在最右侧,则说明需要2*里面的值,否则就是左边这一块+右边那一块。然后就是怎么找对应的右括号,因为是平衡的么。所以我们假设左括号是1,右括号是0,然后遍历,如果sum=0了,那么就表示找到了。
- 大佬的思路——栈:这个思路也是我一直在想的,但是我忽略的一步,我在左括号的时候,没有进行任何操作。大佬的思路是每次我们左括号就入栈0,然后右括号的时候计算完了以后也入栈。具体的计算过程是把栈顶元素取出来,这个就是我们目前遇到的这个括号的值了,进行计算,计算就直接*2即可,因为去除来的值就是括号里面的值,这时候有个问题,就是这个值可能是0,因此我们要再跟1取最大值,这样保证了如果是()的时候,结果就是1。然后这里并没有计算结束,因为这个括号我们计算完了,之前还有结果,也就是并列括号的时候,因此这时候需要再加一下栈顶元素。最后计算完了还需要再入栈。这里还有一个问题,就是只有一个括号的时候,因此我们最开始要线push一个0。
- 大佬的思路——数学:其实,我们要统计的就是()的深度,因为(()())这种形式就是展开以后就是21+21。所以问题就简单了,我们找到所有()然后看一下他的深度就可以了。其深度就是有还有左边进行左右括号抵消后还有多少个左括号。然后最终()结果就是2的深度次方,然后多个()进行累加就可以了。真绝了!这个题让我觉得,我小学数学都没学好。
- 技巧:分治、栈、数学
java代码——分治
class Solution {
public int scoreOfParentheses(String s) {
if (s.length() == 2) {
return 1;
}
int bal = 0, n = s.length(), len = 0;
for (int i = 0; i < n; i++) {
bal += (s.charAt(i) == '(' ? 1 : -1);
if (bal == 0) {
len = i + 1;
break;
}
}
if (len == n) {
return 2 * scoreOfParentheses(s.substring(1, n - 1));
} else {
return scoreOfParentheses(s.substring(0, len)) + scoreOfParentheses(s.substring(len));
}
}
}
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 {
stack.push(Math.max(stack.pop() * 2, 1) + stack.pop());
}
}
return stack.pop();
}
}
java代码——数学
class Solution {
public int scoreOfParentheses(String s) {
int bal = 0, n = s.length(), res = 0;
for (int i = 0; i < n; i++) {
bal += (s.charAt(i) == '(' ? 1 : -1);
if (s.charAt(i) == ')' && s.charAt(i - 1) == '(') {
res += 1 << bal;
}
}
return res;
}
}
- 总结:题目还有挺好玩的,我觉得我最近代码能力下降了,哎。最后还是附一下大佬的链接。