int longestValidParentheses(string s) {
int ans = 0;
stack<int> stk; // 没匹配掉的压入栈中,保存下标
for (int i = 0; i < s.size(); i++) {
if (s[i] == ')' && !stk.empty() && s[stk.top()] == '(') {
stk.pop();
int lastMismatch = stk.empty() ? -1 : stk.top();
ans = max(ans, i - lastMismatch); // 前开后闭
} else {
stk.push(i);
}
}
return ans;
}
vector<string> generateParenthesis(int n) {
vector<string> ans;
search(n, n, "", ans);
return ans;
}
void search(int remainL, int remainR, string paren, vector<string> &ans) {
// 确保 0 <= remainL <= remainR
if (remainL == 0 && remainR == 0) {
ans.push_back(paren);
return;
}
if (remainL > 0) search(remainL - 1, remainR, paren + '(', ans);
if (remainL < remainR) search(remainL, remainR - 1, paren + ')', ans);
}
https://leetcode.com/problems/valid-parenthesis-string
bool checkValidString(string s) {
// 设多出的左括号数leftDiff的范围为[lo, hi]。
// 1. 遇到'(',左括号多1,lo++, hi++;
// 2. 遇到')',左括号少1,lo--, hi--;
// 3. 遇到'*',它可以是'('、空串、')',[lo, hi]内的每个值都可-1、+0、+1,整体扩张lo--, hi++。
// 综上,遇到'('时lo++、其他lo--;遇到')'时hi--,其他hi++。
int lo = 0, hi = 0;
for (char c : s) {
lo += (c == '(') ? 1 : -1;
hi += (c == ')') ? -1 : 1;
// 在扫描过程中,一旦hi<0,leftDiff<0,串无效
if (hi < 0) return false;
// 而lo<0的部分可以直接丢弃,因为有效串的leftDiff>=0
lo = max(lo, 0);
}
// 最终能够leftDiff==0,串才有效
return lo == 0;
}
vector<string> removeInvalidParentheses(string s) {
// 有多少左右括号不匹配待删除,
// rmL和rmR将作为dfs的剪枝条件
int rmL = 0, rmR = 0;
for (char c : s) {
if (c == '(') {
rmL++;
} else if (c == ')') {
if (rmL > 0) rmL--; // 匹配
else rmR++;
}
}
vector<string> ans;
remove(s, 0, 0, rmL, rmR, ans);
return ans;
}
// s[..idx)的左括号比右括号多moreL,s[idx..]有rmL个'('待删除、rmR个')'待删除
void remove(const string &s, int idx, int moreL, int rmL, int rmR, vector<string> &ans) {
if (moreL < 0 || rmL < 0 || rmR < 0) return;
const int N = s.size();
for (int i = idx; i < N && moreL >= 0; i++) {
if (s[i] == '(') {
if (rmL > 0 && (i == idx || s[i] != s[i-1])) { // 连续'('只删第一个
remove(s.substr(0, i) + s.substr(i + 1), i, moreL, rmL - 1, rmR, ans);
}
moreL++;
} else if (s[i] == ')') {
if (rmR > 0 && (i == idx || s[i] != s[i-1])) {
remove(s.substr(0, i) + s.substr(i + 1), i, moreL, rmL, rmR - 1, ans);
}
moreL--;
}
}
if (moreL == 0 && rmL == 0 && rmR == 0) {
ans.push_back(s);
}
}
int scoreOfParentheses(string S) {
// 深度depth的"()"贡献2^depth分
int depth = 0, ans = 0;
for (int i = 0; i < S.size(); i++) {
if (S[i] == '(') depth++;
else {
depth--;
if (S[i-1] == '(') ans += 1 << depth;
}
}
return ans;
}
int minAddToMakeValid(string S) {
int bal = 0, ans = 0;
for (char c : S) {
bal += (c == '(') ? 1 : -1;
if (bal == -1) {
bal++;
ans++;
}
}
ans += bal;
return ans;
}