括号相关算法


括号相关的大多数用栈和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
}
posted @ 2021-04-03 23:53  海拉尔  阅读(98)  评论(0编辑  收藏  举报