1. 程式人生 > >Score of Parentheses 括號的分數

Score of Parentheses 括號的分數

給定一個平衡括號字串 S,按下述規則計算該字串的分數:

  • () 得 1 分。
  • AB 得 A + B 分,其中 A 和 B 是平衡括號字串。
  • (A) 得 2 * A 分,其中 A 是平衡括號字串。

示例 1:

輸入: "()"
輸出: 1

示例 2:

輸入: "(())"
輸出: 2

示例 3:

輸入: "()()"
輸出: 2

示例 4:

輸入: "(()(()))"
輸出: 6

提示:

  1. S 是平衡括號字串,且只含有 ( 和 ) 。
  2. 2 <= S.length <= 50

思路一:直接通過棧來模擬操作,這樣簡單易懂,如果遇到“(”,就壓入棧。如果遇到右括號,判斷棧頂元素是什麼,如果是“(”,證明出現了”()”的情況,那麼把棧頂元素彈出,壓入“1”。如果是其他情況,那麼先判斷棧頂是不是數字,如果是數字,證明是(()())的結構,那麼這時的棧情況是(1,1),所以應該把棧裡的元素相加再壓入棧,一直遇到左括號,這時情況是(2),所以應該把數字2乘以2。再壓入棧,這樣操作完棧裡會有一堆數字,我們把數字相加即可。

class Solution {
public:
    int scoreOfParentheses(string S) {
	stack<string> s;
	for (char c : S) {
		if (c == '(') s.push("(");
		else {
			if (!s.empty() && s.top() == "(") {
				s.pop();
				s.push("1");
			}
			else {
				int tmp = 0;
				while (!s.empty() && s.top() != "(") {
					tmp += stoi(s.top());
					s.pop();
				}
				if (!s.empty()) s.pop();
				tmp *= 2;
				s.push(to_string(tmp));
			}
			
		}
	}
	int res = 0;
	while (!s.empty()) {
		res += stoi(s.top());
		s.pop();
	}
	return res;       
    }
};

思路二:也是用棧,但是思路不一樣(不容易想,但是程式碼灰常簡潔),

字串中的每個位置都有一個深度,圍繞它的一些匹配括號。 例如:(()(.())中的點的深度為2,因為這些括號滿足這個規律:(__(.__))

我們的目標是將目前分數score保持在我們目前所處的深度。 當我們看到一個開括號時,我們增加了深度,我們在新深度的位置插入0。當我們看到一個結束括號時,我們將棧頂元素*2+下一個棧頂元素的的值加入新的棧。

例如,當遇到(()(()))時,我們的堆疊將如下所示:

​​​​​

  • [0, 0] 遇到 (
  • [0, 0, 0] 遇到 (
  • [0, 1] 遇到 )
  • [0, 1, 0] 遇到 (
  • [0, 1, 0, 0]
     遇到 (
  • [0, 1, 1] 遇到 )
  • [0, 3] 遇到 )
  • [6] 遇到 )

參考程式碼:

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