Given a balanced parentheses string `S`, compute the score of the string based on the following rule:

  • () has score 1
  • AB has score A + B, where A and B are balanced parentheses strings.
  • (A) has score 2 * A, where A is a balanced parentheses string.

Example 1:

Input: "()"
Output: 1

Example 2:

Input: "(())"
Output: 2

Example 3:

Input: "()()"
Output: 2

Example 4:

Input: "(()(()))"
Output: 6

Note:

  1. S is a balanced parentheses string, containing only ( and ).
  2. 2 <= S.length <= 50

这道题给了我们一个只有括号的字符串,一个简单的括号值1分,并排的括号是分值是相加的关系,包含的括号是乘的关系,每包含一层,都要乘以个2。题目中给的例子很好的说明了题意,博主最先尝试的方法是递归来做,思路是先找出每一个最外层的括号,再对其中间的整体部分调用递归,比如对于 "()(())" 来说,第一个最外边的括号是 "()",其中间为空,对空串调用递归返回0,但是结果 res 还是加1,这个特殊的处理后面会讲到。第二个最外边的括号是 "(())" 的外层括号,对其中间的 "()" 调用递归,返回1,再乘以2,则得到 "(())" 的值,然后把二者相加,就是最终需要的结果了。找部分合法的括号字符串的方法就是使用跟之前那道题 [Valid Parentheses](http://www.cnblogs.com/grandyang/p/4424587.html) 的相同的方法,使用一个计数器,遇到左括号,计数器自增1,反之右括号计数器自减1,那么当计数器为0的时候,就是一个合法的字符串了,我们对除去最外层的括号的中间内容调用递归,然后把返回值乘以2,并和1比较,取二者间的较大值加到结果 res 中,这是因为假如中间是空串,那么返回值是0,乘以2还是0,但是 "()" 的分值应该是1,所以累加的时候要跟1做比较。之后记得要更新i都正确的位置,参见代码如下:


解法一:

class Solution {
public:
int scoreOfParentheses(string S) {
int res = 0, n = S.size();
for (int i = 0; i < n; ++i) {
if (S[i] == ')') continue;
int pos = i + 1, cnt = 1;
while (cnt != 0) {
(S[pos++] == '(') ? ++cnt : --cnt;
}
int cur = scoreOfParentheses(S.substr(i + 1, pos - i - 2));
res += max(2 * cur, 1);
i = pos - 1;
}
return res;
}
};

我们也可以使用迭代来做,这里就要借助栈 stack 来做,因为递归在调用的时候,其实也是将当前状态压入栈中,等递归退出后再从栈中取出之前的状态。这里的实现思路是,遍历字符串S,当遇到左括号时,将当前的分数压入栈中,并把当前得分清0,若遇到的是右括号,说明此时已经形成了一个完整的合法的括号字符串了,而且除去外层的括号,内层的得分已经算出来了,就是当前的结果 res,此时就要乘以2,并且要跟1比较,取二者中的较大值,这样操作的原因已经在上面解法的讲解中解释过了。然后还要加上栈顶的值,因为栈顶的值是之前合法括号子串的值,跟当前的是并列关系,所以是相加的操作,最后不要忘了要将栈顶元素移除即可,参见代码如下:


解法二:

class Solution {
public:
int scoreOfParentheses(string S) {
int res = 0;
stack<int> st;
for (char c : S) {
if (c == '(') {
st.push(res);
res = 0;
} else {
res = st.top() + max(res * 2, 1);
st.pop();
}
}
return res;
}
};

我们可以对空间复杂度进行进一步的优化,并不需要使用栈去保留所有的中间情况,可以只用一个变量 cnt 来记录当前在第几层括号之中,因为本题的括号累加值是有规律的,"()" 是1,因为最中间的括号在0层括号内,2^0 = 1。"(())" 是2,因为最中间的括号在1层括号内,2^1 = 2。"((()))" 是4,因为最中间的括号在2层括号内,2^2 = 4。因此类推,其实只需要统计出最中间那个括号外变有几个括号,就可以直接算出整个多重包含的括号字符串的值,参见代码如下:


解法三:

class Solution {
public:
int scoreOfParentheses(string S) {
int res = 0, cnt = 0, n = S.size();
for (int i = 0; i < n; ++i) {
(S[i] == '(') ? ++cnt : --cnt;
if (S[i] == ')' && S[i - 1] == '(') res += (1 << cnt);
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/856

类似题目:

Valid Parentheses

参考资料:

https://leetcode.com/problems/score-of-parentheses/

https://leetcode.com/problems/score-of-parentheses/discuss/141777/C%2B%2BJavaPython-O(1)-Space

[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)

[LeetCode] Score of Parentheses 括号的分数的更多相关文章

  1. LeetCode 856. Score of Parentheses 括号的分数

    其实是这道题的变式(某港带同学的C/C++作业) 增加一点难度,输入的S不一定为平衡的,需要自己判断是否平衡,若不平衡输出为0. 题目描述 Given a parentheses string s, ...

  2. Leetcode 856. Score of Parentheses 括号得分(栈)

    Leetcode 856. Score of Parentheses 括号得分(栈) 题目描述 字符串S包含平衡的括号(即左右必定匹配),使用下面的规则计算得分 () 得1分 AB 得A+B的分,比如 ...

  3. [LeetCode]22. Generate Parentheses括号生成

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  4. leetcode 20 Valid Parentheses 括号匹配

    Given a string containing just the characters '(', ')', '{', '}', '[' and']', determine if the input ...

  5. LeetCode 856. 括号的分数(Score of Parentheses)

    856. 括号的分数 856. Score of Parentheses 题目描述 给定一个平衡括号字符串 S,按下述规则计算该字符串的分数: () 得 1 分. AB 得 A + B 分,其中 A ...

  6. LeetCode:括号的分数【856】

    LeetCode:括号的分数[856] 题目描述 给定一个平衡括号字符串 S,按下述规则计算该字符串的分数: () 得 1 分. AB 得 A + B 分,其中 A 和 B 是平衡括号字符串. (A) ...

  7. [LeetCode] 22. Generate Parentheses 生成括号

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  8. [LeetCode] 20. Valid Parentheses 合法括号

    Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...

  9. LeetCode:有效的括号【20】

    LeetCode:有效的括号[20] 题目描述 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. ...

随机推荐

  1. P5305 [GXOI/GZOI2019]旧词

    题目地址:P5305 [GXOI/GZOI2019]旧词 这里是官方题解 \[\sum_{i \leq x}^{}\ depth(lca(i,y))^k\] \(k = 1\) 求的是 \(\sum_ ...

  2. 基于注解的SpringMVC添加其他的Servlet、Filter以及Listener

    我们可以在AbstractAnnotationConfigDispatcherServletInitializer的实现类中重写onStartup(ServletContext servletCont ...

  3. linux下双网卡双网关配置

    要求: eth0:192.168.100.203 连接内网,网关为192.168.100.1.需要和192.168.10.0.192.168.12.0.192.168.100.0.10.2.2.0.1 ...

  4. 使用nc传输文件和目录【转】

    方法1,传输文件演示(先启动接收命令) 使用nc传输文件还是比较方便的,因为不用scp和rsync那种输入密码的操作了 把A机器上的一个rpm文件发送到B机器上 需注意操作次序,receiver先侦听 ...

  5. VUE 滚动插件(better-scroll)

    1. 概述 1.1 说明 better-scroll是一款重点解决移动端(已支持PC)各种滚动场景需求的插件.例如淘宝聚划算中的类型选择(女装/家纺/生鲜美食等),没有滚动条显示却实现了滚动功能. 1 ...

  6. 详解MariaDB数据库的索引

    1.什么是索引 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针. 更通俗的说,数据库索引好比是一本书前面的目录,在查找内容之前可以先在 ...

  7. 出错:Failed to convert property value of type 'org.apache.ibatis.session.defaults.DefaultSqlSessionFactory' to required type 'java.lang.String' for property 'sqlSessionFactoryBeanName';

    出错的详细信息: 3 ERROR [http-nio-80-exec-3] org.springframework.web.servlet.DispatcherServlet - Context in ...

  8. java PageHelper 分页插件出现 Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Duplicate column name 'Id' 错误

    情景: Mapper.xml定义连表查询,如果sql的字段名中有sql关键字,会导致PageHelper插件出现 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntax ...

  9. tp5 修改默认的分页url

    默认分页url:xx.com/xxx?page=1 个人主要感觉不美观,想变成xx.com/xxx/list_1.html这样的 框架本身默认使用的boostrap分页类,目录位置 simplewin ...

  10. C#控制台或应用程序中两个多个Main()方法的设置

    大多数初级程序员或学生都认为在C#控制台或应用程序中只能有一个Main()方法.但是事实上是可以有多个Main()方法的. 在C#控制台或应用程序中,在多个类中,且每个类里最多只能存在一个Main() ...