[LeetCode] 856. Score of Parentheses 括號的分數



Given a balanced parentheses string S, compute the score of the string based on the following rule:html

  • () 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:git

Input: "()"
Output: 1

Example 2:github

Input: "(())"
Output: 2

Example 3:優化

Input: "()()"
Output: 2

Example 4:code

Input: "(()(()))"
Output: 6

Note:htm

  1. S is a balanced parentheses string, containing only ( and ).
  2. 2 <= S.length <= 50



這道題給了咱們一個只有括號的字符串,一個簡單的括號值1分,並排的括號是分值是相加的關係,包含的括號是乘的關係,每包含一層,都要乘以個2。題目中給的例子很好的說明了題意,博主最早嘗試的方法是遞歸來作,思路是先找出每個最外層的括號,再對其中間的總體部分調用遞歸,好比對於 "()(())" 來講,第一個最外邊的括號是 "()",其中間爲空,對空串調用遞歸返回0,可是結果 res 仍是加1,這個特殊的處理後面會講到。第二個最外邊的括號是 "(())" 的外層括號,對其中間的 "()" 調用遞歸,返回1,再乘以2,則獲得 "(())" 的值,而後把兩者相加,就是最終須要的結果了。找部分合法的括號字符串的方法就是使用跟以前那道題 Valid Parentheses 的相同的方法,使用一個計數器,遇到左括號,計數器自增1,反之右括號計數器自減1,那麼當計數器爲0的時候,就是一個合法的字符串了,咱們對除去最外層的括號的中間內容調用遞歸,而後把返回值乘以2,並和1比較,取兩者間的較大值加到結果 res 中,這是由於假如中間是空串,那麼返回值是0,乘以2仍是0,可是 "()" 的分值應該是1,因此累加的時候要跟1作比較。以後記得要更新i都正確的位置,參見代碼以下:blog



解法一:遞歸

class Solution {
public:
    int scoreOfParentheses(string S) {
        int res = 0, n = S.size();
        for (int i = 0; i < n; ++i) {
            if (S[i] == ')') continue;
            int pos = i + 1, cnt = 1;
            while (cnt != 0) {
                (S[pos++] == '(') ? ++cnt : --cnt;
            }
            int cur = scoreOfParentheses(S.substr(i + 1, pos - i - 2));
            res += max(2 * cur, 1);
            i = pos - 1;
        }
        return res;
    }
};



咱們也可使用迭代來作,這裏就要藉助棧 stack 來作,由於遞歸在調用的時候,其實也是將當前狀態壓入棧中,等遞歸退出後再從棧中取出以前的狀態。這裏的實現思路是,遍歷字符串S,當遇到左括號時,將當前的分數壓入棧中,並把當前得分清0,若遇到的是右括號,說明此時已經造成了一個完整的合法的括號字符串了,並且除去外層的括號,內層的得分已經算出來了,就是當前的結果 res,此時就要乘以2,而且要跟1比較,取兩者中的較大值,這樣操做的緣由已經在上面解法的講解中解釋過了。而後還要加上棧頂的值,由於棧頂的值是以前合法括號子串的值,跟當前的是並列關係,因此是相加的操做,最後不要忘了要將棧頂元素移除便可,參見代碼以下:leetcode



解法二:字符串

class Solution {
public:
    int scoreOfParentheses(string S) {
        int res = 0;
        stack<int> st;
        for (char c : S) {
            if (c == '(') {
                st.push(res);
                res = 0;
            } else {
                res = st.top() + max(res * 2, 1); 
                st.pop();
            }
        }
        return res;
    }
};



咱們能夠對空間複雜度進行進一步的優化,並不須要使用棧去保留全部的中間狀況,能夠只用一個變量 cnt 來記錄當前在第幾層括號之中,由於本題的括號累加值是有規律的,"()" 是1,由於最中間的括號在0層括號內,2^0 = 1。"(())" 是2,由於最中間的括號在1層括號內,2^1 = 2。"((()))" 是4,由於最中間的括號在2層括號內,2^2 = 4。所以類推,其實只須要統計出最中間那個括號外變有幾個括號,就能夠直接算出整個多重包含的括號字符串的值,參見代碼以下:



解法三:

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



Github 同步地址:

https://github.com/grandyang/leetcode/issues/856



相似題目:

Valid Parentheses



參考資料:

https://leetcode.com/problems/score-of-parentheses/

https://leetcode.com/problems/score-of-parentheses/discuss/141777/C%2B%2BJavaPython-O(1)-Space



LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索