【题目】
给定一个字符串str,判断是不是整体有效的括号字符串。例如,str = “()()()”,返回True,str = “())” 或 “()a()”,返回False。
【补充题目】
给定一个括号字符串,返回最长的有效字符串的长度。
【基本思路】
原问题。判断过程如下:
- 从左到右遍历str,判断每一个字符是否是括号,如果不是,直接返回False。
- 遍历过程中,检查目前位置 ‘(‘和 ‘)’的数量,如果 ‘)’的数量多,直接返回False。
- 遍历结束后,检查 ‘(‘和 ‘)’的数量是否相同,如果一样多返回True,否则返回False。
补充问题。使用动态规划,类似于最长递增子序列问题。假设str的长度为N,生成长度为N的dp数组,dp[i]的含义是必须以str[i]结尾的最长有效括号长度子串。dp的求解如下:
dp[0],表示只含有一个括号,dp[0] = 0。
如果dp[i] == ‘(‘,肯定不能作为末尾,dp[i] = 0。
- 如果dp[i] == ‘)’,dp[i-1]的含义是以str[i-1]结尾的最长有效子串长度,如果 i – dp[i-1] – 1位置上的字符是 ‘(‘,则可以与dp[i]凑成一对,则此时dp[i]最小等于dp[i-1] + 2。此外,如果 i – dp[i-1] – 1位置上的字符变成了有效字符,那么以该位置的前一个位置 i – dp[i-1] – 2的最长有效长度也应该加进来,所以dp[i] = dp[i-1] + 2 + dp[i – dp[i-1] – 2]。
dp[0…N-1]中最大的值就是最长的有效字符串的长度。
下面是使用python3.5实现的代码
#括号字符串的有效性和最长有效长度
#原题目
def isValid(str1):
if str1 == None or len(str1) == 0:
return False
status = 0
for i in range(len(str1)):
if str1[i] != '(' and str1[i] != ')':
return False
elif str1[i] == '(':
status += 1
else:
status -= 1
if status < 0:
return False
return status == 0
#补充题目
def maxValidLength(str1):
if str1 == None or len(str1) == 0:
return 0
dp = [0 for i in range(len(str1))]
res = 0
for i in range(1, len(str1)):
if str1[i] == ')':
pre = i - dp[i-1] - 1
if pre >= 0 and str1[pre] == '(':
dp[i] = dp[i-1] + 2 + dp[pre-1] if pre > 0 else 0
res = max(res, dp[i])
return res