题目描述:
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: “(()”
Output: 2
Explanation: The longest valid parentheses substring is “()”
Example 2:
Input: “)()())”
Output: 4
Explanation: The longest valid parentheses substring is “()()”
题目大意:
- 如题所述,给定一个字符串,要求寻找到其中的最长的,有效的,子字符串
- 何为有效?这道题之所以等级是hard,因为这道题的基础在这里LeetCode算法题之20. Valid Parentheses(easy)
- 因为这里只让你关注一种符号即可,也就是圆括号,但是想法思路,判断有效与否,是一样的
解题思路:
- 首先想到的是将所有的子字符串,全部找到,依次判定有效与否,有效的,记录长度,比较,哪个长,返回那个值,实践得知:超时了!(Time Limit Exceed)
- 所以还是从如何判定字符串有效与否,这个条件入手
- 因为只要你有效,无论你有多少种组合形式,无论你有多长,你的“(” 的数量,与“)” 的数量,一定是相等的,尽管在内部怎么变
- 所以我们就可以设置两个变量,left,与right,分别记录“(” 的数量,和“)”的数量
- 依次遍历字符串时,遇“(”, left+1, 遇“)”, right+1,当相等时,就说明那个子字符串,是有效的
- 在从左至右遍历时,当出现right>left时,说明有效的字符串结束了,多了一个“)”了
- 应该全部重新赋值0,继续下一波寻找
- 这样就能准确找出最长的子字符串?答案是不能
- 因为当你遇到“((())”,这种结构时,就会错失那个最长的字符串了(假设4是答案)
- 看代码会发现,解决方案是,从右至左,又重复了一遍上面的操作,这个是什么意思和原理?
- 因为假如最长的字符串是”(())“,它只有两种情况被上面的想法所错过,一个是左边多”(“,一个是右边多”)“,而且不可能两边同时多
- 这样一来,重复两遍,不重不漏,时间复杂度O(n),不会超时
少废话,上代码:
class Solution:
def longestValidParentheses(self, s):
max_len, left, right = 0, 0, 0
#从左向右查找
for i in s:
if i == "(":
left += 1
else:
right += 1
if left == right:
l = 2 * right
max_len = max(max_len, l)
elif right > left:
left, right = 0, 0
left, right = 0, 0
#从右向左,在查找一边查找,保证不漏
for i in reversed(s):
if i == ")":
right += 1
else:
left += 1
if left == right:
l = 2 * right
max_len = max(max_len, l)
elif left > right:
left, right = 0, 0
return max_len
运行时间和内存占用:
- Runtime: 48 ms, faster than 41.73% of Python3 online submissions for Longest Valid Parentheses.
- Memory Usage: 13.8 MB, less than 38.89% of Python3 online submissions for Longest Valid Parentheses.