法一:
1.容易想到,左括号不等于右括号数量,就不行,输出-1
2.转成括号序列问题,遇到左括号+1,遇到右括号-1;
然后括号匹配,当前缀和为0的时候为合法序列。前缀和为负的时候为“可以更改成合法的非法序列”
参考思路
法二:
搞个栈,贪心
1.容易想到,左括号不等于右括号数量,就不行,输出-1
2.每次遇到右括号 弹出栈顶左括号;如果遇到右括号,前面栈中却没有左括号,说明这个序列需要我们去更改。比如)(
如果每次遇到右括号前面都有左括号与它匹配就是个合法的括号,权值为0;比如(()())
思路2代码
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+100; int n; char s[maxn]; stack<char> st; int main(){ cin>>n; int allLeft = 0,allRight = 0; for(int i=1;i<=n;i++) { cin>>s[i]; if(s[i] == '(') allLeft++; else allRight++; } if(allLeft != allRight){ puts("-1"); return 0; } int left = 0,right = 0; int ans = 0; bool flag2 = true; for(int i=1;i<=n;i++){ if(s[i] == '(') { left++; st.push('('); } else { //每次遇到右括号 弹出栈顶左括号 //如果遇到右括号,前面栈中却没有左括号,说明这个序列需要我们去更改 right++; if(flag2 && !st.empty()){ if(st.top() == '('){ st.pop(); }else flag2 = false; }else flag2 = false; } if(left == right){ if(flag2 == false){ ans += left*2; } left = 0; right = 0; flag2 = true; while(!st.empty()) st.pop(); //手动清空栈 } } cout<<ans; return 0; } /* 8 ))((())( 4 (()) 6 ((())) 6 (()()) */
来源:https://www.cnblogs.com/fisherss/p/12450559.html