一【题目类别】
- 栈
二【题目难度】
- 中等
三【题目编号】
- 856.括号的分数
四【题目描述】
- 给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:
- () 得 1 分。
- AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。
- (A) 得 2 * A 分,其中 A 是平衡括号字符串。
五【题目示例】
- 示例 1:
输入: “()”
输出: 1 - 示例 2:
输入: “(())”
输出: 2 - 示例 3:
输入: “()()”
输出: 2 - 示例 4:
输入: “(()(()))”
输出: 6
六【题目提示】
- S 是平衡括号字符串,且只含有 ( 和 ) 。
- 2 <= S.length <= 50
七【解题思路】
- 经观察发现,只有遇到"()“才能得分,而得分只分两种情况,一种是单独的”()“只得一分,另一种是嵌套的”()",所以我们只需要计算嵌套的"()",而一层得1分,两层得2分 所以找到规律,嵌套的"()“分数就是2^层数-1,而其他括号分数无需再计算,所以遇到”(“时层数增加,遇到”)"时根据层数计算分数
八【时间频度】
- 时间复杂度: O ( N ) O(N) O(N)
九【代码实现】
- Java语言版
package Stack;
import java.util.Stack;
public class p856_ScoreOfParentheses {
public static void main(String[] args) {
String S = "(()(()))";
int res = scoreOfParentheses(S);
System.out.println("res = " + res);
}
public static int scoreOfParentheses(String S) {
// 新建一个栈,这个栈不是用来存放字符的,而是字符对应的得分
Stack<Integer> stack = new Stack<Integer>();
// 初始当前深度为0,得分为0
stack.push(0);
// 遍历每一个字符,分别对三种情况说明(注:其实()和()()型判断得分的方式一样,只是(AB)型判断的方式不一样)
// 如果遇到(就将0入栈,说明还没有与之配对的,如果遇到)说明遇到了一个与之配对的,那么pop出两个元素,对应的分数就为1,再将新的分数push
// ①、如果在上面的情况遇到了(,则继续将0入栈,还没有与之配对的
// ②、如果在最上面的初始条件又遇到了),则说明现在肯定有(AB)型的,则pop出两个元素,这两个元素对应就是AB的分数,将其*2,但是还要加上最后一次pop的分数,因为要计算分数和,这里使用max是因为第一次)进入可能正好形成(),但是如果再次进入),说明肯定事(AB)型,所以要取最大值
for (char c : S.toCharArray()) {
if (c == '(') {
stack.push(0);
} else {
int c1 = stack.pop();
int c2 = stack.pop();
stack.push(c2 + Math.max(2 * c1, 1));
}
}
return stack.pop();
}
}
- C语言版
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
/*使用数组模拟栈*/
#define MAX_COUNT 50
int p856stack[MAX_COUNT] = { 0 };
int p856stack_top = 0;
/*初始化栈*/
void p856stack_init()
{
p856stack_top = 0;
memset(p856stack, 0, sizeof(p856stack));
}
/*入栈*/
void p856stack_push(int num)
{
p856stack[p856stack_top++] = num;
}
/*出栈*/
int p856stack_pop()
{
int num = p856stack[p856stack_top - 1];
p856stack[--p856stack_top] = 0;
return num;
}
int scoreOfParentheses(char *S)
{
/*新建一个栈,这个栈不是用来存放字符的,而是字符对应的得分*/
p856stack_init();
/*初始当前深度为0,得分为0*/
p856stack_push(0);
/*如果遇到(就将0入栈,说明还没有与之配对的,如果遇到)说明遇到了一个与之配对的,那么pop出两个元素,对应的分数就为1,再将新的分数push*/
/*①、如果在上面的情况遇到了(,则继续将0入栈,还没有与之配对的*/
/*②、如果在最上面的初始条件又遇到了),则说明现在肯定有(AB)型的,则pop出两个元素,这两个元素对应就是AB的分数,将其*2,但是还要加上最后一次pop的分数,因为要计算分数和,这里使用max是因为第一次)进入可能正好形成(),但是如果再次进入),说明肯定事(AB)型,所以要取最大值*/
for (int i = 0; i < strlen(S); i++)
{
if (S[i] == '(')
{
p856stack_push(0);
}
else
{
int c1 = p856stack_pop();
int c2 = p856stack_pop();
p856stack_push(c2 + ((c1 * 2) > 1 ? (c1 * 2) : 1));
}
}
return p856stack_pop();
}
/*主函数省略*/
十【提交结果】
-
Java语言版
-
C语言版