括号字符串的有效性和最长有效长度
是否为整体有效的括号字符串
【题目】
给定一个字符串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
有任何疑问和建议,欢迎在评论区留言和指正!
感谢您所花费的时间与精力!