直觉上采用stack是可以解决这个问题的,但是本题只要求返回一个对应的长度,而非相应的括号序列,那么如果不用stack能否可行呢。
考虑从左向右的情况
如果遇到")",此时应该采取的动作有两个,其一是左侧已有"(",即构成有效的的括号对;其二就是作为分界点,此时左侧能取到的最长有效括号对,就是截止到此处位置的当前解。此处可写出第一版:
max_length = 0
left_account = 0
right_account = 0
for item in s:
if item == '(':
left_account += 1
else:
# no right bigger
if right_account == left_account:
left_account = 0
right_account = 0
continue
else:
right_account += 1
if left_account == right_account:
max_length = max(max_length, left_account + right_account)
return max_length
但是,此时忽略了一个问题,比如case "(((((((((()",左括号数量永远多余右括号,这样在此处,永远无法判断到right == left,即valid不可达到。当然直观的想法是,再外套一层循环,在每个位置都执行相应操作,但是,能不能更简单一点。
既然我们考虑的是"("在从左向右的特殊性,那么另一个右括号")",在从右向左的情况下,不就应该也有一样的特殊性?
考虑从右往左的情况
直接将上述的代码再写一遍,并稍作修改,第二版:
max_length = 0
left_account = 0
right_account = 0
for item in s:
if item == '(':
left_account += 1
else:
# no right bigger
if right_account == left_account:
left_account = 0
right_account = 0
continue
else:
right_account += 1
if left_account == right_account:
max_length = max(max_length, left_account + right_account)
reverse_max_length = 0
reverse_left_account = 0
reverse_right_account = 0
for item in s[::-1]:
if item == ')':
reverse_right_account += 1
else:
if reverse_right_account == reverse_left_account:
reverse_left_account = 0
reverse_right_account = 0
continue
else:
reverse_left_account += 1
if reverse_left_account == reverse_right_account:
reverse_max_length = max(
reverse_max_length,
reverse_left_account + reverse_right_account
)
return max(max_length, reverse_max_length)
AC,时间复杂度 O(n), 空间复杂度O(1)。