LeetCode 856. 括号的分数

856. 括号的分数

 

LeetCode 856. 括号的分数_第1张图片

【计算贡献度】其实可以把每一对括号看作某个深度的叶子结点,我们可以根据他所在的层数计算他对最终答案的贡献度,以( () ()(()) )这个为例子,最外层的 () 包裹了一个 () 和一个 ()(()) 然后再把后面的拆分成 () 和 (()),这样其实就相当于三部分的和了,分别是:(()), (()), ((()))这样就成了计算两个深度为2,一个深度为4的括号的和了。

那么深度如何来计算呢,当遇到 '(' 的时候,我们把深度t + 1,当遇到 ')' 的时候,把深度 t - 1,如果前面一个是 '(' ,那么就把答案加上 1 << t。比如 (( )) 这个,t从0到1再到2然后变为1的时候就可以计算对整个的贡献度了,然后后面再遇到 ')' 只是把深度 - 1,相当于跳出括号,不再去加贡献度了。

class Solution {

    // 4:33
    // 计算贡献度

    public int scoreOfParentheses(String s) {
        int t = 0, n = s.length(), ans = 0, b = 1;
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == '(') {
                t++;
            } else {
                t--;
                if (t == 0) {
                    ans += b; b = 1;
                } else {
                    b *= 2;
                }
            }
        }
        return ans;
    }
}

【栈模拟】如果用栈来模拟这个过程的话,需要每次遇到 '(' 的时候在栈顶压入一个0作为辅助。每次遇到 '(' 的时候压入一个0,遇到 ')' 的时候弹出栈顶验证,如果是0,就把1和加到栈顶元素上,如果不是0,就把这个数的2倍加上栈顶元素上。

以( () (()) )为例子:栈初始为0

遇到(,变为0, 0

遇到(,变为0, 0, 0

遇到),弹出栈顶0,变为0,0,然后把1和此时栈顶相加变为0, 1

遇到(,变为0, 1, 0

遇到(,变为0, 1, 0, 0

遇到),弹出栈顶0,变为0, 1, 0,然后把1和栈顶相加变为0, 1, 1

遇到),弹出栈顶1,变为0, 1,然后把1 * 2和栈顶元素相加变为0, 3

遇到),弹出栈顶3,变为0,然后把3 * 2 和栈顶元素相加变为6。得到最终答案。

class Solution {

    // 栈
    // 9:42

    // ( () (()) )
    // 6


    public int scoreOfParentheses(String s) {
        Deque stack = new LinkedList();
        stack.push(0);
        for (var i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') stack.push(0);
            else {
                int top = stack.poll();
                if (top == 0) stack.push(stack.pop() + 1);
                else stack.push(stack.pop() + top * 2);
            }
        }
        int ans = 0;
        while (!stack.isEmpty()) ans += stack.poll();
        return ans;
    }
}

 

 

 

你可能感兴趣的:(LeetCode,栈,括号匹配)