Stack 栈
题目 - 1249. 移除无效的括号
https://leetcode.cn/problems/minimum-remove-to-make-valid-parentheses/
给你一个由 '('、')' 和小写字母组成的字符串 s。
你需要从字符串中删除最少数目的 '(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效。
请返回任意一个合法字符串。
有效「括号字符串」应当符合以下 任意一条 要求:
空字符串或只包含小写字母的字符串 可以被写作 AB(A 连接 B)的字符串,其中 A 和 B 都是有效「括号字符串」 可以被写作 (A) 的字符串,其中 A 是一个有效的「括号字符串」
- 像这种括号匹配的题目基本都需要用栈来处理。 因为所有右括号都是与最近的左括号匹配的,所以可以用栈来记录所有未匹配的左括号。
时间复杂度:O(n) 空间复杂度:O(n)
func minRemoveToMakeValid(s string) string {
// available[i] 表示 s[i] 是否合法,初始化均不合法
available := make([]bool, len(s))
// stack 存储当前可供匹配的左括号
stack := make([]int, 0)
// 带下标遍历 s 中的每一个字符
for i, ch := range s {
// 根据字符种类进行不同处理
if ch == '(' {
// 如果是左括号,则直接把当前下标压入栈中,
// 因为当前左括号可能会与后续的右括号匹配
stack = append(stack, i)
} else if ch == ')' {
// 如果是右括号,此时若栈中还有左括号,
// 则当前括号对合法
if len(stack) > 0 {
// 标记左括号合法
available[stack[len(stack)-1]] = true
// 标记右括号合法
available[i] = true
// 弹出该左括号的下标 j
stack = stack[:len(stack)-1]
}
} else {
// 如果是其他字符,则必定合法,标记即可
available[i] = true
}
}
// ans 收集所有合法的字符
ans := bytes.Buffer{}
// 遍历 s 中的每一个字符
for i, ch := range s {
// 如果该字符合法,则放入 ans 中
if available[i] {
ans.WriteRune(ch)
}
}
// 返回 ans 中的字符串
return ans.String()
}