算法小知识-----10.09----- 括号的分数

157 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情

眨眨眼就是第二个周一了,连上7天班,单独部署还悬在头顶,不知道什么时候落下

括号的分数

该题出自力扣的856题 —— 括号的分数【中等题】

审题

给定一个平衡括号字符串 S,按下述规则计算该字符串的分数: () 得 1 分。 AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。 (A) 得 2 * A 分,其中 A 是平衡括号字符串。

  • 这道题其实还挺麻烦的,确实也是错了挺多次。给出一个特定的字符串,里面只包含'('和')'两种字符。并且需要遵循三种特定的业务规则
    • 如果是最底层的"()",1分
    • "()()"这种由两者独立出来的,1+1 = 2分
    • "(())"这种包裹住的,1*2 = 2分
  • 最开始想的是暴力遍历过去,但是暴力的时候需要带上业务规则,所以最初是设置了两个变量下标,一个是标志当前左括号左边是否存在左括号,一个是标志右括号是否为最后。但是无论换哪一种暴力循环过去,都无可避免需要考虑层次的问题。需要记录当前的右括号是在哪一层结束的。例如"(() ()))" 这一种用例,需要记录第一个(),和第二个(())的和的乘2
  • 因此最后还是向社会屈服,学习了别人的(偷看)
  • 也是和自己想法一样,开辟一个栈存储括号,并且在弹栈的时候做判断
    • 先存储一个初始值0,作为防止越界
    • 循环字符串,如果是"("直接压栈
    • 如果是")",弹出栈顶一位,栈顶的必定是"("。相当于抵消了"()"
    • 然后再弹出栈顶一位,取出当前值,并且与 上一位栈顶乘2与1的最大值做相加,相当于前缀和的数组
    • 最终返回栈顶即可

编码

class Solution {
    public int scoreOfParentheses(String s) {
        Deque<Integer> deque = new ArrayDeque<>();
        deque.addLast(0);
        for(int i = 0;i<s.length();i++){
            char c = s.charAt(i);
            if (c == '('){
                deque.addLast(0);
            }else{
                int cur = deque.pollLast();
                deque.addLast(deque.pollLast() + Math.max(cur *2,1));
            }
        }
        return deque.peekLast();
    }
}

image.png