制作营销网站公司北京百度seo工作室
文章目录
- 1. 题目来源
- 前置题目:
- 2. 题目解析
1. 题目来源
链接:2116. 判断一个括号字符串是否有效
前置题目:
题单:
- 待补充
2. 题目解析
这个题目,灵神 的分析十分十分巧妙,很值得多读几遍。也是从本题中,能窥看到 括号匹配 问题的内在本质。
方法一:一次遍历。
- 问题分析:详细的可以直接移步灵神题解。
2025年03月23日16:44:59
记录一下自己对本题的理解:
- 括号匹配问题,在任意下标下,只用关心左括号的未匹配个数即可,记为 C。
- 遇到左括号则 +1,右括号则 -1。
- 如果中途 C < 0 则说明右括号大于了左括号个数,不匹配。
- 否则遍历完毕仅需判断 C==0 即可得到整个括号序列是否匹配。
以上是常规的匹配过程,但对本题来说,有部分下标可以变成左括号、右括号 其中一种。
- 那么对于 C 的变化,就不是一个确定的值,而是一个 取值集合。
- 遍历完毕后,最终这个取值集合里面包含了数值 0,则说明有解,否则无解。
至于代码实现过程,不需要真的去维护这个取值集合。而是关注这个集合中的最大值、最小值即可。
- 最大值在变化过程中 < 0,说明前缀的右括号过多,一定无解。
- 最小值在变化过程中 < 0,说明取值集合可能是 {0,2,4} 向 {1,3} 这样子转变。那么就需要将最小值赋值为 1。
- 最后判断最小值是否等于 0 即可。
注意这个集合中的数字,都是连续奇数、连续偶数,且都是大于等于 0 的,这个可以通过简单的数学归纳法证明。
这个写法十分巧妙,且容易理解,包括灵神的例子也十分巧妙。
先记录在此,看看什么时候复习的时候想不起来了,再来复习hh…
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
func canBeValid(s string, locked string) bool {n := len(s)if n % 2 != 0 { // 如果是奇数长度,一定无解return false}mn, mx := 0, 0 // 左括号的取值集合的最大值、最小值for i, v := range s {if locked[i] == '1' { // 如果它不可变d := 1 if v == ')' {d = -1}mx += d // 记录最大值变化if mx < 0 { // 如果左括号最大值都小于 0,说明右括号过多,一定无解return false}mn += d // 记录最小值变化} else { // 该位置可变mx ++ // 变左括号,左括号未匹配的最大值 ++mn -- // 变右括号,左括号未匹配的最小值 --}// 如果左括号最小值过程中 < 0。实际上现在的结果集合是从 {0,2,4} 变为了 {1,3} 这样子// 因为上述在不可变的情况下,已经判断了无解情况。// 在可变情况下,一定可以将 mn 变为 1。if mn < 0 { mn = 1}}return mn == 0
}