时间复杂度:O(n),空间复杂度:O(1)
解题思路
如果看过我“22.括号生成”题解的朋友,应该会很容易理解这一题的思路。
LeetCode0022.括号生成 Go语言AC笔记https://blog.csdn.net/Hexa_H/article/details/127058909用left和right记录匹配子串的左右括号数,每当遇到左括号时就令left加1,遇到右括号时right加1但接下来需要做一下判断:如果left刚好等于right,就说明有括号匹配上了,匹配子串长度加2;但如果right大于left了,说明该右括号是多余的无法匹配,就令left和right置0重新计算长度。
细心的朋友会发现,按照上述方法有一种情况会出现错误,那就是left>right即有多余的左括号,所以按照上述方法我们只能做对右括号多余的例子。不过我们可以调整下思维,从右向左遍历把右括号当作左括号不就可以做对左括号多余的例子了嘛。
所以正常情况下该题需要从左向右和从右向左分别遍历一次,但是其实可以将两次不同方向的遍历合为一次遍历,在从左向右遍历时同时遍历镜像方向不就好了嘛。
AC代码
func longestValidParentheses(s string) (res int) {
//1是从左向右遍历,2是从右向左遍历
leftCount1,rightCount1,leftCount2,rightCount2,n:=0,0,0,0,len(s)
//一次遍历求出结果
for i:=0;i<n;i++{
if s[i]=='('{
leftCount1++
}else{
rightCount1++
if leftCount1==rightCount1{
res=max(res,leftCount1+rightCount1)
}else if rightCount1>leftCount1{
leftCount1,rightCount1=0,0
}
}
if s[n-1-i]==')'{
rightCount2++
}else{
leftCount2++
if leftCount2==rightCount2{
res=max(res,leftCount2+rightCount2)
}else if leftCount2>rightCount2{
leftCount2,rightCount2=0,0
}
}
}
return res
}
func max(a,b int) int {
if a>b{
return a
}
return b
}
感悟
受之前做题的影响,其实绝大多数两次相反方向的遍历都可以用一次遍历解决,这样可以更快速的解题。