1. 程式人生 > >【LeetCode】856. Score of Parentheses 解題報告(Python & C++)

【LeetCode】856. Score of Parentheses 解題報告(Python & C++)

作者: 負雪明燭
id: fuxuemingzhu
個人部落格: http://fuxuemingzhu.cn/


目錄

題目地址:https://leetcode.com/problems/score-of-parentheses/description/

題目描述

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分,如果AB形式得2分,如果(A)分數是2×A.求最終多少分。

解題方法

括號匹配的題目一般要用到棧,這個題也是。我們用棧儲存兩樣東西:一是左括號(,二是得分。這樣我們在遇到)返回的時候,可以直接判斷棧裡面是左括號還是得分。如果是左括號(,那麼得分是1,放入棧中。如果是得分,那麼我們需要一直向前求和直到找到左括號為止,然後把這個得分×2,放入棧中。

由於題目給的是符合要求的括號匹配對,那麼棧裡面最後應該只剩下一個元素了,就是最終得分。

Python程式碼如下:

class Solution(object):
    def scoreOfParentheses(self, S):
        """
        :type S: str
        :rtype: int
        """
        stack = []
        score = 0
        for c in S:
            if c == '(':
                stack.append("(")
            else:
                tc = stack[-1]
                if tc == '(':
                    stack.pop()
                    stack.append(1)
                else:
                    num = 0
                    while stack[-1] != '(':
                        num += stack.pop()
                    stack.pop()
                    stack.append(num * 2)
        return sum(stack)

如果一個棧裡面只放數值的話,那麼,我們可以把遇到的左括號變成0放到棧裡面。我們遇到右括號的時候,把前面的數字乘以2重新放入棧的末尾,但是()是直接放入1的。為了防止棧為空,那麼在棧開始的時候放入一個0,當把棧過了一遍之後,剩餘的數字就是所求。

用官方例子說明:

For example, when counting (()(())), our stack will look like this:

[0, 0] after parsing (
[0, 0, 0] after (
[0, 1] after )
[0, 1, 0] after (
[0, 1, 0, 0] after (
[0, 1, 1] after )
[0, 3] after )
[6] after )

python程式碼如下:

class Solution(object):
    def scoreOfParentheses(self, S):
        """
        :type S: str
        :rtype: int
        """
        stack = [0]
        score = 0
        for c in S:
            if c == '(':
                stack.append(0)
            else:
                v = stack.pop()
                stack[-1] += max(v * 2, 1)
        return sum(stack)

遞迴

這個遞迴解法,我們使用的是從兩頭向中間的策略。如果找到的了()返回1,否則向中間找有沒有提前匹配好的,這個如果存在就是AB形式,返回的是A+B。如果不存在的話,那說明是(A)形式,就返回2×A.

注意,在找AB的時候,i從l開始只能迴圈到r - 1,最後的一個括號不能進行匹配。

此處輸入圖片的描述

C++程式碼如下:

class Solution {
public:
    int scoreOfParentheses(string S) {
        return helper(S, 0, S.size() - 1);
    }
private:
    int helper(string& s, int l, int r) {//[l, r]
        if (r - l == 1) return 1;
        int count = 0;
        for (int i = l; i < r; i++) {
            if (s[i] == '(')
                count++;
            else
                count--;
            if (count == 0) {
                return helper(s, l, i) + helper(s, i + 1, r);
            }
        }
        return helper(s, l + 1, r - 1) * 2;
    }
};

計數

我們從左到右去統計,開放的'('數目為d,如果遇到一個(就意味著裡面的()要加倍。當我們遇到()的時候,需要增加2^(d-1)到結果裡面。這個方法只關注()

此處輸入圖片的描述

C++程式碼如下:

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

日期

2018 年 12 月 11 日 —— 雙十一已經過去一個月了,真快啊。。