【算法】括号问题

1. 合法括号深度

一个合法的括号匹配序列有以下定义:
1、空串""是一个合法的括号匹配序列
2、如果"X"和"Y"都是合法的括号匹配序列,"XY"也是一个合法的括号匹配序列
3、如果"X"是一个合法的括号匹配序列,那么"(X)"也是一个合法的括号匹配序列
4、每个合法的括号序列都可以由以上规则生成。
例如: "","()","()()","((()))"都是合法的括号序列
对于一个合法的括号序列我们又有以下定义它的深度:
1、空串""的深度是0
2、如果字符串"X"的深度是x,字符串"Y"的深度是y,那么字符串"XY"的深度为max(x,y) 3、如果"X"的深度是x,那么字符串"(X)"的深度是x+1
例如: "()()()"的深度是1,"((()))"的深度是3。牛牛现在给你一个合法的括号序列,需要你计算出其深度。 

def depth(s):
    left = 0
    res = 0
    for i in range(len(s)):
        if s[i] == '(':
            left += 1
            res = max(left, res)
        else:
            left -= 1
    return res

2. 补充缺失括号

一个完整的括号字符串定义规则如下:
1、空字符串是完整的。
2、如果s是完整的字符串,那么(s)也是完整的。
3、如果s和t是完整的字符串,将它们连接起来形成的st也是完整的。
例如,"(()())", ""和"(())()"是完整的括号字符串,"())(", "()(" 和 ")"是不完整的括号字符串。
牛牛有一个括号字符串s,现在需要在其中任意位置尽量少地添加括号,将其转化为一个完整的括号字符串。请问牛牛至少需要添加多少个括号。 

def valid(s):
    left = 0 #需要与之匹配的左括号个数
    right = 0 #需要与之匹配的右括号个数
    for i in range(len(s)):
        if s[i] == '(':
            left += 1
        if s[i] == ')':
            if left == 0:
                right += 1
            else:
                left -= 1
    return left + right

3. 有效的括号

给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

class Solution:
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        left = []
        right = []
        for i in range(len(s)):
            if s[i] in ["(","[","{"]:
                left.append(s[i])
            else:
                right.append(s[i])
                if left == []:
                    return False
                if (s[i] == ')' and left[-1] == '(') or (s[i] == ']' and left[-1] == '[') or (s[i] == '}' and left[-1] == '{'):
                    left.pop()
                    right.pop()
        if left == [] and right == []:
            return True
        else:
            return False

4. 最长有效括号(dp)

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

class Solution:
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        if s == '':
            return 0
        dp = [0 for i in range(len(s))]
        for i in range(1,len(s)):
            index = i-dp[i-1]-1
            if index >= 0 and s[i] == ')' and s[index] == '(':
                dp[i] = dp[i-1] + 2
                if index - 1 > 0:
                    dp[i] += dp[index-1]
                
        
        return max(dp)

5. 生成括号

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

class Solution:
    def __init__(self):
        self.list = []
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        if n == 0:
            return ''
        self.generate('',self.list,n,n)
        return self.list
    
    def generate(self, sub, l, left, right):
        if left > right:
            return
        if left > 0:
            self.generate(sub + '(', self.list, left-1, right)
        if right > 0:
            self.generate(sub + ')', self.list, left, right-1)
        if left == 0 and right == 0:
            self.list.append(sub)
            return 

6. 使括号有效的最少添加

https://leetcode-cn.com/problems/minimum-add-to-make-parentheses-valid/

给定一个由 '(' 和 ')' 括号组成的字符串 S,我们需要添加最少的括号( '(' 或是 ')',可以在任何位置),以使得到的括号字符串有效。

从形式上讲,只有满足下面几点之一,括号字符串才是有效的:

  • 它是一个空字符串,或者
  • 它可以被写成 AB (A 与 B 连接), 其中 A 和 B 都是有效字符串,或者
  • 它可以被写作 (A),其中 A 是有效字符串。

给定一个括号字符串,返回为使结果字符串有效而必须添加的最少括号数。

class Solution(object):
    def minAddToMakeValid(self, S):
        """
        :type S: str
        :rtype: int
        """
        #每遇到一次不合法(没有左括号匹配当前右括号),结果就加一
        num= 0
        res = 0
        for item in S:
            if num < 0:
                res += 1
                num = 0
            if item == "(":
                num += 1
            else:
                num -= 1
        #最后若num不为0,则剩余的也是不合法的
        res += abs(num)
        return res

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值