class Solution {
public:
bool canBeValid(string s, string locked) {
}
};
2116. 判断一个括号字符串是否有效
一个括号字符串是只由 '('
和 ')'
组成的 非空 字符串。如果一个字符串满足下面 任意 一个条件,那么它就是有效的:
()
.AB
(A
与 B
连接),其中A
和 B
都是有效括号字符串。(A)
,其中 A
是一个有效括号字符串。给你一个括号字符串 s
和一个字符串 locked
,两者长度都为 n
。locked
是一个二进制字符串,只包含 '0'
和 '1'
。对于 locked
中 每一个 下标 i
:
locked[i]
是 '1'
,你 不能 改变 s[i]
。locked[i]
是 '0'
,你 可以 将 s[i]
变为 '('
或者 ')'
。如果你可以将 s
变为有效括号字符串,请你返回 true
,否则返回 false
。
示例 1:
输入:s = "))()))", locked = "010100" 输出:true 解释:locked[1] == '1' 和 locked[3] == '1' ,所以我们无法改变 s[1] 或者 s[3] 。 我们可以将 s[0] 和 s[4] 变为 '(' ,不改变 s[2] 和 s[5] ,使 s 变为有效字符串。
示例 2:
输入:s = "()()", locked = "0000" 输出:true 解释:我们不需要做任何改变,因为 s 已经是有效字符串了。
示例 3:
输入:s = ")", locked = "0" 输出:false 解释:locked 允许改变 s[0] 。 但无论将 s[0] 变为 '(' 或者 ')' 都无法使 s 变为有效字符串。
提示:
n == s.length == locked.length
1 <= n <= 105
s[i]
要么是 '('
要么是 ')'
。locked[i]
要么是 '0'
要么是 '1'
。原站题解
golang 解法, 执行用时: 48 ms, 内存消耗: 6.8 MB, 提交时间: 2022-11-18 17:03:34
func canBeValid(s string, locked string) bool { if len(s) % 2 == 1 { return false } // 注:由于这里 len(s) 是偶数,所以循环结束后 x 也是偶数(这意味着可以通过配对来让括号平衡度为 0),无需判断 x 是否为奇数 // x 是偶数是因为每遍历一个字符必然会改变 x 的奇偶性,而 x 的奇偶性在发生偶数次变化后的结果是 x 的奇偶性不变 x := 0 for i, ch := range s { if ch == '(' || locked[i] == '0' { x++ } else if x > 0 { x-- } else { return false } } x = 0 for i := len(s) - 1; i >= 0; i-- { if s[i] == ')' || locked[i] == '0' { x++ } else if x > 0 { x-- } else { return false } } return true }
python3 解法, 执行用时: 332 ms, 内存消耗: 15.7 MB, 提交时间: 2022-11-18 17:01:55
class Solution: def canBeValid(self, s: str, locked: str) -> bool: n = len(s) mx = 0 # 可以达到的最大分数 mn = 0 # 可以达到的最小分数 与 最小有效前缀对应分数 的较大值 for i in range(n): if locked[i] == '1': # 此时对应字符无法更改 if s[i] == '(': diff = 1 else: diff = -1 mx += diff mn = max(mn + diff, (i + 1) % 2) else: # 此时对应字符可以更改 mx += 1 mn = max(mn - 1, (i + 1) % 2) if mx < mn: # 此时该前缀无法变为有效前缀 return False # 最终确定 s 能否通过变换使得分数为 0(成为有效字符串) return mn == 0