括号相关的大多数用栈和dp,或者左右各自遍历一遍
lt20 合法括号
用栈,遍历string,左半边则入栈,右边则检查栈是否空和栈顶是否匹配。
- c++
vector<char>str;
bool isValid(string s) {
for(int i=0;i<s.size();i++)
{
if(s[i]=='('||s[i]=='{'||s[i]=='[')
str.push_back(s[i]);
else{
if(!str.empty()&&str.back()==get(s[i]))
{
str.pop_back();
}else{
return false;
}
}
}
return str.size()==0;
}
char get(char x)
{
if(x=='}')
return '{';
else if(x==')')
return '(';
else
return '[';
}
- golang 版本
func isValid(s string) bool {
//左边入栈,遇到右边判断,最后栈空则true
stack:=make([]byte,0)
for i:=0;i<len(s);i++{
if s[i]=='('||s[i]=='['||s[i]=='{'{
stack = append(stack,s[i])
}else{
if len(stack)!=0&&stack[len(stack)-1]==getChar(s[i]){
stack = stack[:len(stack)-1]
}else{
return false
}
}
}
return len(stack)==0
}
//获取对应字符
func getChar(str byte)byte{
if str==')'{
return '('
}else if str ==']'{
return '['
}else{
return '{'
}
}
22 括号生成
- dfs,左括号数量小于右括号有效
func generateParenthesis(n int) []string {
res:=make([]string,0)
var dfs func(left int,right int,path string)
dfs = func(left int,right int,path string){
if n*2==len(path){
res = append(res,path)
return
}
if left>0{ //左边括号数还存在,则增加
dfs(left-1,right,path+"(")
}
if left<right{//右括号数量剩余多,则放置右括号
dfs(left,right-1,path+")")
}
}
dfs(n,n,"")
return res
}
32 最长有效括号
求最长有效括号,三种方法,栈,dp,左右遍历
- 栈
func longestValidParentheses(s string) int {
//栈放置下标,遇到)且无(匹配则重新计数
stack:=make([]int,0)
stack = append(stack,-1)//先1放置-1
res:=0
for i:=0;i<len(s);i++{
if s[i]=='('{
stack = append(stack,i)
}else{
stack = stack[:len(stack)-1] //连续两个),第二个)会弹出第一个),然后stack空,第二个)位置的index入栈
if len(stack)==0{ //没有和)匹配,入栈作为下次计算的初始
stack = append(stack,i)
}else{
res = max(res,i-stack[len(stack)-1])
}
}
}
return res
}
func max(x,y int)int{
if x>y{
return x
}else{
return y
}
}
- dp,考虑多种情况,略复杂 O(n) O(n)
func longestValidParentheses(s string) int {
//dp 考虑多种情况
dp:=make([]int,len(s)) //dp[i] 代表到i结尾字符串最长有效括号长度
res:=0
for i:=1;i<len(s);i++{ //s[i]=='(' 无匹配直接省略 从1开始,第0位'('或者')'都是无匹配
if s[i]==')'{
if i-1>=0&&s[i-1]=='('{
if i-2>=0{
dp[i] = dp[i-2]+2
}else{
dp[i] = 2
}
}else if i-dp[i-1]-1>=0&&s[i-dp[i-1]-1]=='('{ //((...))情况
if i-dp[i-1]-2>=0{
dp[i] = dp[i-dp[i-1]-2]+dp[i-1]+2 // ()((...))情况
}else{
dp[i] = dp[i-1]+2
}
}
}
res = max(res,dp[i])
}
return res
}
func max(x,y int)int{
if x>y{
return x
}else{
return y
}
}
- 贪心,左右各一遍
func longestValidParentheses(s string) int {
//贪心,左右各自来一次
res:=0
left,right:=0,0
for i:=0;i<len(s);i++{
if s[i]=='('{
left++
}else{
right++
}
if left==right{
res = max(res,2*left)
}else if right>left{
left,right = 0,0
}
}
left,right = 0,0
//从右向左
for i:=len(s)-1;i>=0;i--{
if s[i]=='('{
left++
}else{
right++
}
//左比右多则left,right归零
if left==right{
res = max(res,2*left)
}else if left>right{
left,right=0,0
}
}
return res
}
func max(x,y int)int{
if x>y{
return x
}else{
return y
}
}
678有效的括号字符串
可以当(,),或者空串
- 栈 O(n) O(n)
func checkValidString(s string) bool {
//双栈存储(和* ,遇到)优先匹配(,最后处理*空串
left,star:=make([]int,0),make([]int,0)
for i:=0;i<len(s);i++{
if s[i]=='('{
left = append(left,i)
}else if s[i]=='*'{
star = append(star,i)
}else{
if len(left)!=0{
left =left[:len(left)-1] //优先匹配(
}else if len(star)!=0{
star = star[:len(star)-1]
}else{
return false //没有对应的匹配直接返回
}
}
}
//结束如果(存在*存在继续把*当作)匹配,多余的*当作空串
for len(left)!=0&&len(star)!=0{
if left[len(left)-1]>star[len(star)-1]{ //(在*右边,不符合
return false
}
left = left[:len(left)-1]
star = star[:len(star)-1]
}
//最后如果(没有对应匹配则不符合
return len(left)==0
}