32. 最长有效括号
难度:困难
问题描述:
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
示例 3:
输入:s = ""
输出:0
方法一
分析:
1、将“()”作为一个子串,查找其在原串s中的索引号并存储在a列表中
2、对a列表中数据进行处理:
(1)如果a的长度为0,返回0
(2)如果a的长度不为0,则统计索引号连续出现的次数,这个连续不是指索引号以0、1、2、3......这样的形式出现,而是以类似0、2、4、6、......或1、3、5、7、......这样的形式出现,因为“()”是一个整体,占用两个位置,找出这些出现次数的最大值
3、最长有效括号是最大次数的两倍
程序如下:
#函数khlist(s)生成“()”在原串s中的索引号形成的列表a
def khlist(s):
a=[]
p='()'
n=s.count(p)
w=0
for i in range(n):
k=s.index(p,w)
a.append(k)
w=k+1
return a
#对a列表中数据进行处理,返回“()”连续出现的最大次数
def maxkh(a):
print(a)
if len(a)==0:
return 0
else:
n=len(a)
m=1
k=a[0]
maxl=1
for i in range(1,n):
if a[i]==k+2:
m=m+1
k=a[i]
if i==n-1 and m>maxl:
maxl=m
else:
if m>maxl:
maxl=m
m=1
k=a[i]
return maxl
s=input('pls input s=')
print(2*maxkh(khlist(s)))
运行实例1:
pls input s=(()()()())))
[1, 3, 5, 7]
8
运行实例2:
pls input s=()()()))()()()()())))
[0, 2, 4, 8, 10, 12, 14, 16]
10
方法二:
在上面程序能够正确运行输出结果时,我又发现一个更加简便的方法:
因为最长有效括号子串的长度肯定是小于s的长度,而且其长度肯定是偶数,所以“()”在s中出现的次数分两种情况:
- 如果s的长度是偶数,则“()”出现的次数最多是len(s)/2
- 如果s的长度是奇数,则“()”出现的最大次数是(len(s)-1)/2
基于这样的分析,只要在s串中去查找不同长度连续括号即可找到最长有效括号子串了
程序如下:
s=input('pls input s=')
a='()'
n=len(s)
if n%2==0:
k=n//2
else:
k=(n-1)//2
maxl=0
i=1
while i<=k:
if i*a in s and 2*i>maxl:
maxl=2*i
i=i+1
print(maxl)
运行实例1:
pls input s=()()()))()()()())))
8
运行实例2:
pls input s=(((
0
从本题的解决可以看出,有完善的编程逻辑控制,有优秀的数据结构支持,可以编出解决问题的程序,但如果有更加巧妙的算法,则事半功倍。