Valid Parentheses
Given a string containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.
The brackets must close in the correct order, “()” and “()[]{}” are all valid but “(]” and “([)]” are not.
class Solution {
public:
bool isValid(string s) {
stack<char> par;
string spLeft{"([{"},spRight{")]}"},sp=spLeft+spRight;
for(const char &cm:s)
{
if(sp.find(cm)==-1) continue;
if(!par.empty())
{
int iLeft=spLeft.find(par.top());
int iRight=spRight.find(cm);
if(iLeft==iRight)
{
par.pop();
}
else
{
par.push(cm);
}
}
else
{
par.push(cm);
}
}
return par.empty();
}
};
匹配成功最后栈为空。其中重要的部分是如何确定两个能够匹配,之后出栈。这里采用的索引比较。
Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
class Solution {
public:
void parenthesis(int left,int right,vector<string> &v)
{
string s{v.back()};
if(left>0&&right>0)//left取值>=0
{
auto iter=v.rbegin();
*iter+="(";
parenthesis(left-1,right,v);
}
if(right)
{
if(left<right)
{
if(left>0)
{
s+=")";
v.push_back(s);
}
else
{ //没有左括号,只剩余右括号添加
auto iter=v.rbegin();
*iter+=")";
}
parenthesis(left,right-1,v);
}
}
}
vector<string> generateParenthesis(int n) {
vector<string> v{};
if(n!=0)
{
v.push_back("(");
parenthesis(n-1,n,v);
}
return v;
}
};
这个也还好,就是左右括号在递归中的分配。两个int监督左右括号剩余多少。对右括号要把握好。
Longest Valid Parentheses
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
For “(()”, the longest valid parentheses substring is “()”, which has length = 2.
Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.
class Solution {
public:
int longestValidParentheses(string s) {
if(s.empty()) return 0;
int len=s.length();
vector<int> f(len);
f[0]=0;
stack<pair<char,int>> cp;//int记录上一个没有被匹配的索引
cp.push({s[0],0});
for(int i=1;i<len;++i)
{
if(cp.empty())
{
cp.push({s[i],i});
f[i]=0;
}
else
{
if(s[i]==')'&&cp.top().first=='(')
{
cp.pop();
if(cp.empty())
{
f[i]=i+1;;
}
else//存在未匹配
{
f[i]=i-cp.top().second;
}
}
else
{
cp.push({s[i],i});
f[i]=0;
}
}
}
return *(max_element(f.begin(),f.end()));
}
};
这个题目就开始难了,动态规划,状态应该是匹配成功,至于转移方程应该是选之前与现在最大。我不是完全这么写的,动态规划学得也并不是很好。我是每个索引对应记录他那个地方匹配成功的字符串长度。然后取最大。怎么记录那个字符串长度,用了int帮助记录,如)()())在stack中的记录应该是)0,(1,)2等等,在4处匹配成功,pop出栈匹配字符,栈顶元素为)0,故4-0=4。此时4处记录的字符串长度为4。
注意:pair在stack中使用。
Remove Invalid Parentheses
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
Note: The input string may contain letters other than the parentheses ( and ).
Examples:
“()())()” -> [“()()()”, “(())()”]
“(a)())()” -> [“(a)()()”, “(a())()”]
“)(” -> [“”]
class Solution {
public:
static bool compare(string &s1,string &s2)
{
return s1.length()>s2.length();
}
//i:索引,del=left-right(除掉遗弃部分),left、right:左右括号使用情况,has:左括号已有个数
void removeIn(vector<string> &v,string &s,int i,int del,int left,int right,int has)
{
if(i>=s.length()) return;
string str=v.back();
if(s[i]=='(')
{
if(right>0&&has!=right)
{
if(del-1>=0)//后面左括号还有很多,可以省。
{
removeIn(v,s,i+1,del-1,left-1,right,has);//省
str+="(";
v.push_back(str);
}
else
{
auto iter=v.rbegin();
*iter+="(";
}
removeIn(v,s,i+1,del,left-1,right,has+1);//不省
}
else
{
removeIn(v,s,i+1,del-1,left-1,right,has);//省
}
}
else if(s[i]==')')
{
if(right>0&&has>0)
{
if(has<=right-1)
{
removeIn(v,s,i+1,del+1,left,right-1,has);//省
str+=")";
v.push_back(str);
}
else
{
auto iter=v.rbegin();
*iter+=")";
}
removeIn(v,s,i+1,del,left,right-1,has-1);//不省
}
else
{
removeIn(v,s,i+1,del+1,left,right-1,has);//省
}
}
else
{
auto iter=v.rbegin();
*iter+=s[i];
removeIn(v,s,i+1,del,left,right,has);
}
}
vector<string> removeInvalidParentheses(string s) {
vector<string> v{""};
if(s.empty()) return v;
int left=0,right=0;
for(const char &cm:s)//count ( and )
{
if(cm=='(')
{
++left;
}
else if(cm==')')
{
++right;
}
}
string str{v.back()};
if(s[0]=='(')
{
if(left>right&&right>0)
{
removeIn(v,s,1,left-right-1,left-1,right,0);
if(right>0)
{
str+="(";
v.push_back(str);
}
}
else if(right>0)
{
auto iter=v.rbegin();
*iter+="(";
}
removeIn(v,s,1,left-right,left-1,right,1);
}
else if(s[0]==')')
{
removeIn(v,s,1,left-right+1,left,right-1,0);
}
else
{
auto iter=v.rbegin();
*iter+=s[0];
removeIn(v,s,1,left-right,left,right,0);
}
sort(v.begin(),v.end(),compare);
for(auto iter=v.begin(),iter1=iter+1;iter1!=v.end();)
{
if(iter->length()>iter1->length())
{
v.erase(iter1,v.end());
break;
}
else
{
++iter;
++iter1;
}
}
set<string> sets(v.begin(),v.end());
vector<string> ve(sets.begin(),sets.end());
return ve;
}
};
说实话,这个对我来说,有点难,代码写得逻辑并不是很清晰。我记录两点,以供以后再修改:
A、sort是用来将短的字符串放在尾端,好删除,留下长的。
B、set是用来去重。