Given a string `S` of `'('` and `')'` parentheses, we add the minimum number of parentheses ( `'('` or `')'`, and in any positions ) so that the resulting parentheses string is valid.
Formally, a parentheses string is valid if and only if:
- It is the empty string, or
- It can be written as
AB
(A
concatenated withB
), whereA
andB
are valid strings, or - It can be written as
(A)
, whereA
is a valid string.
Given a parentheses string, return the minimum number of parentheses we must add to make the resulting string valid.
Example 1:
Input: "())"
Output: 1
Example 2:
Input: "((("
Output: 3
Example 3:
Input: "()"
Output: 0
Example 4:
Input: "()))(("
Output: 4
Note:
S.length <= 1000
S
only consists of'('
and')'
characters.
這道題給了一個括號字符串,可能是非法的,讓我們補充最少數量的半括號,使其變為合法的括號字符串。那么實際上只要統計出需要添加的左右括號個數即可,這里使用兩個變量 left 和 right,分別表示需要的左右括號個數。遍歷字符串S,若遇到左括號,說明此時需要右括號,則 right 自增1;若遇到了右括號,若此時 right 大於0,說明當前的右括號可以用來匹配之前的左括號,不需要另加右括號,所以此時 right 自減1;而若此時 right 為0,說明當前的右括號前面沒有左括號可以跟其匹配,則此時 left 自增1,表示需要額外的左括號。最后返回 left+right 即為所求,參見代碼如下:
解法一:
class Solution {
public:
int minAddToMakeValid(string S) {
int left = 0, right = 0;
for (char c : S) {
if (c == '(') {
++right;
} else if (right > 0) {
--right;
} else {
++left;
}
}
return left + right;
}
};
我們可以只用一個變量 cnt,表示當前左括號的個數。遍歷字符串S,當遇到左括號,而此時 cnt 為負數時,表示此時右括號是多余左括號的,而當前遇到的左括號不能匹配之前的右括號,所以將 cnt 的絕對值加到結果 res 中,表示需要這多么的左括號來匹配之前多出的右括號。然后此時 cnt 自增1,因為當前遇到的是左括號,若當前遇到右括號,則 cnt 自減1,最終返回 res 加上 cnt 的絕對值即為所求,參見代碼如下:
解法二:
class Solution {
public:
int minAddToMakeValid(string S) {
int res = 0, cnt = 0;
for (char c : S) {
if (c == '(') {
if (cnt < 0) {
res += abs(cnt);
cnt = 0;
}
++cnt;
} else {
--cnt;
}
}
return res + abs(cnt);
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/921
類似題目:
Different Ways to Add Parentheses
參考資料:
https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/
[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)