32. Longest Valid Parentheses

直觉上采用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)。

你可能感兴趣的:(32. Longest Valid Parentheses)