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

16 篇文章 0 订阅

Given a balanced parentheses string s, return the score of the string.

The score of a balanced parentheses string is 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: s = “()”
Output: 1

Example 2:

Input: s = “(())”
Output: 2

Example 3:

Input: s = “()()”
Output: 2

Constraints:

2 <= s.length <= 50
s consists of only ‘(’ and ‘)’.
s is a balanced parentheses string.

s是一个仅包含"(" 和 ")"的字符串,

把" ( " 之前最后一个" ) “结尾的括号块叫做一部分。
比如” () ()", 每个" ()" 叫做一部分。
又如" () (())“中,”()“和”(())"分别叫做一部分。

"( )“是1分, 几部分的串接是把各部分分数相加。
外面套一圈”( )“是把分数x2,套2层”( )"就是x2x2,以此类推。

思路:
方法一:
利用stack。
stack用来保存每部分计算的分数,遇到" ( "时,把分数push进去。
而变量score用来计算当前部分的分数,

最终把stack中保存的分数(前面部分)和score(当前部分)相加即可。
遇到" ( “就push当前score,score重置为0,
遇到” ) “取出栈顶的分数,加上当前部分的score,
当前这部分怎么算呢,遇到第一个” ) "是1,后面依次x2,

举个例子" ( () (()) )"
到第一个" ) “时,stack中已压入0, 0, 当前score=0,
这时score = stack.pop() + Max(1, score * 2) = 1,
其中 Max(1, score * 2)这步是
if(score == 0) score = 1;
else score = score * 2的简写。
然后又遇到了” ( ",stack中push刚计算出的score=1 , 这时stack中为0, 1, score重置为0,后面的依次类推。

//1ms
    public int scoreOfParentheses(String s) {
        Stack<Integer> st = new Stack<>();
        int score = 0;
        
        for(int i = 0; i < s.length(); i ++) {
            char ch = s.charAt(i);
            
            if(ch == '(') {
                st.push(score);
                score = 0;
            } else {
                score = st.pop() + Math.max(2 * score, 1);
            }
        }
        return score;
    }

方法二:
分配律。
比如" ( () (()) )",正常我们是要计算(1 + 2) x 2的,
现在把最左边的" ( "用两次,即分配律,变成了计算1x2 + 2x2。

另外,遇到多个连续" ) " 的情况,只计算一次,一下子x2n,后面的都跳过。
那么这个n是多少呢,就是左边与之匹配的" ( “个数-1。
比如 " (( ))”,第一个" ) “时,左边匹配2个” ( ", 那score就是22-1=2,

同样需要一个变量score作为结果的分数,变量tmp用来计算当前部分的分数。
用left表示匹配的" ( " 个数,

回到" ( () (()) )",第一个" ) “时,left = 2, score = 2left-1=2,
相当于” () “分配了一个x2, 然后去掉一个匹配,left–,
遇到下一个” ( ", 相当于一个新的部分,保存score += tmp,tmp重新置0,
" ( “多了一个,left++,
到” ) “时,left = 3, tmp=2left-1=4,后面是连续的” ) ",已经都计算完了,跳过。

所以两部分加起来就是1x2 + 2x2

    public int scoreOfParentheses(String s) {
        int left = 0;
        int score = 0;
        int tmp = 0;
        boolean right = false;
        
        for(int i = 0; i < s.length(); i ++) {
            char ch = s.charAt(i);
            
            if(ch == '(') {
                left ++;
                score += tmp;
                tmp = 0;
                right = false;
            } else {
                left --;
                if(right) continue;
                tmp = 1 << left;
                right = true;
            }
        }
        score += tmp;
        return score;
    }

代码简化一下

    public int scoreOfParentheses(String s) {
        int left = 0;
        int score = 0;
        
        for(int i = 0; i < s.length(); i ++) {
            char ch = s.charAt(i);
            
            if(ch == '(') {
                left ++;
            } else {
                left --;
                if(s.charAt(i-1) == '(') score += 1 << left;
            }
        }
        
        return score;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值