LeetCode每日一题2020.7.04 32. 最长有效括号

Posted lalal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode每日一题2020.7.04 32. 最长有效括号相关的知识,希望对你有一定的参考价值。

32. 最长有效括号

给定一个只包含 ‘(‘‘)‘ 的字符串,找出最长的包含有效括号的子串的长度。

示例:

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

分析:

? 本题可以用动态规划解决。动态规划的结构是,括号字符串的下标i,dp[i]则表示前i个字符中最长有效括号的长度

? 接着考虑转移方程,

  1. (s[i] == ‘)‘ and s[i - 1] == ‘(‘):

    可以判断出至少有一对匹配成功,如"......()......"。

    如果字符串为"...((()",则也是只有一对匹配。

    但如果字符串为"...()()()",则(dp[i] = dp[i - 2] + 2),即将之前的有效结果加上。

    归纳一下,即:

    (dp[i] = dp[i - 2] + 2, if s[i] == ‘)‘ and s[i - 1]==‘(‘)

    • 同时应该注意边界条件
  2. 如果字符串类似"...((()))",对于最后一个下标如何进行状态转移?

    首先,最里层嵌套括号对右括号dp结果应该为2,接着到第二层括号的右括号")",往左寻找是否有对应的左括号"("。如何寻找那个应该与他对应的左括号呢?只要下标减去中间有效括号的长度即可。同时,应该注意查找前面是否还有一段有效括号。即:

    (dp[i] = egin{cases}dp[i-1] + 2 ext{, if s[i] == ‘)‘ and s[i-1] == ‘)‘ and s[i - s[i - 1] - 1] == ‘(‘} end{cases})

    • 同时应该注意边界条件

? 官方题解还给出了利用 来判断括号匹配关系,以及一种 不需要额外空间的方法。

代码(Golang):

// 一、动态规划:
func longestValidParentheses(s string) int {
	maxAns := 0
	dp := make([]int, len(s))
	for i := 1; i < len(s); i++ {
		if s[i] == ‘)‘ {
			if s[i - 1] == ‘(‘ {
				if i >= 2 {
					dp[i] = dp[i - 2] + 2
				} else {
					dp[i] = 2
				}
			} else if i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == ‘(‘ {
				if i - dp[i - 1] >= 2 {
					dp[i] = dp[i - 1] + dp[i - dp[i - 2] - 2] + 2
				} else {
					dp[i] = dp[i - 1] + 2
				}
			}
			maxAns = max(maxAns, dp[i])
		}
	}
}

func max(nums ...int) int {
	max := nums[0]
	for i := 1; i < len(nums); i++ {
		if nums[i] > max {
			max = nums[i]
		}
	}
	return max
}


// 二、栈:
func longestValidParentheses1(s string) int {
	maxAns := 0
	var stack []int
	stack = append(stack, -1)
	for i := 0; i < len(s); i++ {
		if s[i] == ‘(‘ {
			stack = append(stack, i)
		} else {
			stack = stack[:len(stack) - 1]
			if len(stack) == 0 {
				stack = append(stack, i)
			} else {
				maxAns = max(maxAns, i - stack[len(s) - 1])
			}
		}
	}
	return maxAns
}


// 三、不需要额外的空间:
func longestValidParentheses2(s string) int {
	left, right, maxLength := 0, 0, 0
	for i := 0; i < len(s); i++ {
		if s[i] == ‘(‘ {
			left++
		} else {
			right++
		}
	}
	if left == right {
		maxLength = max(maxLength, 2 * right)
	} else if left > right {
		left, right = 0, 0
	}
	return maxLength
}




以上是关于LeetCode每日一题2020.7.04 32. 最长有效括号的主要内容,如果未能解决你的问题,请参考以下文章

leetcode每日一题-191:位1的个数

《LeetCode之每日一题》:44.位1的个数

leetcode每日一题——六月4号

leetcode每日一题——六月4号

LeetCode 每日一题 50. Pow(x, n)

LeetCode 每日一题 50. Pow(x, n)