括号字符串的有效性和最长有效长度

本文探讨了括号字符串的有效性判断及获取最长有效括号子串的算法。介绍了整体有效的括号字符串判断方法,通过遍历字符串并计数左右括号来判断是否匹配,以及使用动态规划策略获取最长有效括号子串长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

括号字符串的有效性和最长有效长度

是否为整体有效的括号字符串

【题目】
给定一个字符串s,判断是不是整体有效的括号字符串。

【举例】
s = “()”,返回True;
s = “(()())”,返回True;
s = “(())”,返回True。
s = “())”。返回False;
s = “()(”,返回False;
s = “()a()”,返回False。


算法思路

整体有效的括号字符串是指匹配的圆括号弧"()",无其他括号
遍历整个字符串s
  若遇到除’(‘和’)‘之外的字符,直接返回False
  more意为右圆括弧’)‘比左圆括弧’(‘多出的数量,若遇到’)’,more加1,若遇到’(’,more减1,若more > 0直接返回False
  遍历结束后,若左右圆括弧数量不相等(more != 0)返回False,否则返回True
整个过程遍历整个字符串s,没有申请开辟额外空间,因此算法时间复杂度为 O ( N ) O(N) O(N),空间复杂度为 O ( 1 ) O(1) O(1)


相应代码
# 是否为整体有效的括号字符串
def is_valid_par(s):
    if s is None or len(s) == 0:
        return False
    more = 0
    for i in range(len(s)):
        if s[i] != '(' and s[i] != ')':
            return False
        elif s[i] == '(':
            more += 1
        else:
            more -= 1
            if more < 0:
                return False
    if more == 0:
        return True
    else:
        return False
      
# 简单测试
if __name__ == '__main__':
    print(is_valid_par("()"))  # True
    print(is_valid_par("(()())"))  # True
    print(is_valid_par("(())"))  # True
    print(is_valid_par("())"))  # False
    print(is_valid_par("()("))  # False
    print(is_valid_par("()a()"))  # False
    

获取最长的有效括号子串

【补充题目】
给定一个括号字符串s,返回最长的有效括号子串。

【举例】
s = “(()())”,返回6;
s = “())”,返回2;
s = “()(()()(”,返回4。

算法思路

动态规划,dp[i]表示以i结尾的有效括号子串最大长度
  若dp[i-1]无有效匹配(dp[i-1]=0),则比较s[i]s[i-1]是否匹配为圆括号(s[i-1]='(',s[i]=')'),e.g. “()(())”,加粗的表示匹配的圆括号,带下划线为比较的两个字符;
  若dp[i-1]有最长匹配,则比较判断s[i]s[pre]是否匹配为圆括号,其中pre = i - dp[i - 1] - 1,e.g. “()(())”;
  因此综合两者,则比较判断s[i]s[pre]是否匹配为圆括号,其中dp[i] = dp[i-1]+2
  最容易让人疏忽的是s[i]s[pre]匹配为圆括号,还要加上pre-1的最大匹配子串长度dp[i]+=dp[pre-1],e.g. "()(())
  遍历整个字符串s,获取最长的有效括号子串长度返回。
整个过程遍历整个字符串s,申请开辟额外空间dp,因此算法时间复杂度为 O ( N ) O(N) O(N),空间复杂度为 O ( N ) O(N) O(N)


相应代码
# 获取最长的有效括号子串
def get_max_len(s):
    if s is None or len(s) == 0:
        return 0
    # dp[i]表示以i结尾的有效括号子串最大长度
    dp = [0 for i in range(len(s))]
    max_len = 0
    for i in range(1, len(s)):
        if s[i] == ')':
            pre = i - dp[i - 1] - 1
            if s[pre] == '(':
                dp[i] = dp[i - 1] + 2
                if pre > 1:
                    dp[i] += dp[pre - 1]
        if dp[i] > max_len:
            max_len = dp[i]
    return max_len
# 简单测试
if __name__ == '__main__':
    print(get_max_len("(()())"))  # 6
    print(get_max_len("())"))  # 2
    print(get_max_len("()(()()("))  # 4
    print(get_max_len("()(())"))  # 6

有任何疑问和建议,欢迎在评论区留言和指正!

感谢您所花费的时间与精力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值