leetcode 856. 括号的分数

92 阅读1分钟

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

1. 题目与解析

给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:

  • () 得 1 分。
  • AB 得 A + B 分,其中 A 和 B 是平衡括号字符串。
  • (A) 得 2 * A 分,其中 A 是平衡括号字符串。   输入: "()"

输出: 1

输入: "(())"

输出: 2

输入: "()()"

输出: 2

输入: "(()(()))"

输出: 6

根据题意可知,我们可以将整体的计算过程分解成两部分。

第一部分是括号内的计算:

  • 第一种情况()间没有数字,这时我们直接将1作为括号整体计算后的结果返回就可以了;
  • 第二种情况,()间有内容,这时需要注意的一点是,()间是可能存在嵌套的形式的,所以还需要考虑这里的计算。

第二部分是括号间的计算:

  • 这部分的计算相对简单,是加法计算。

2. 题解

为了更好的进行上述计算,我们可以考虑使用栈结构进行计算,计算时可能会遇到的几种情况:

  1. 首先是如果遇到(,那么就在栈中压入一个-1作为标记位;
  2. 其次,如果遇到),那么我们就需要计算一组()的返回值了,这个时候按照我们上一节提到的空与非空两种情况讨论,总体代码如下:
Stack<Integer> sta = new Stack<>();
for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    if (c == '(') {
        sta.push(-1);
    } else {
        int pop = sta.pop(), tmp = 0;
        while (pop != -1) {
            tmp += pop;
            pop = sta.pop();
        }
        if (tmp == 0) {
            tmp = 1;
        } else {
            tmp *= 2;
        }
        sta.push(tmp);
    }
        }

进行了上述计算后,我们的栈中剩下的就是N个数字了,代表最外层并列的需要相加的几组()的返回值,这时,取出来相加就是我们需要的答案。

int ans = sta.pop();
while (!sta.isEmpty()) {
    ans += sta.pop();
}

return ans;

总体的解题代码如下所示:

class Solution {
    public int scoreOfParentheses(String s) {
        Stack<Integer> sta = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') {
                sta.push(-1);
            } else {
                int pop = sta.pop(), tmp = 0;
                while (pop != -1) {
                    tmp += pop;
                    pop = sta.pop();
                }
                if (tmp == 0) {
                    tmp = 1;
                } else {
                    tmp *= 2;
                }
                sta.push(tmp);
            }
        }

        int ans = sta.pop();
        while (!sta.isEmpty()) {
            ans += sta.pop();
        }

        return ans;
    }
}