一日一练:栈匹配

71 阅读1分钟

1. 有效的括号

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。满足条件:1. 左括号必须用相同类型的右括号闭合; 2. 左括号必须以正确的顺序闭合。

栈的使用

遇到相匹配的字符时将对应字符从栈中弹出,否则将自身压入栈中。

function isValid(s: string): boolean {
  const stack = []
  for (let i = 0; i < s.length; i++) {
    if (
      (s[i] === ')' && stack[stack.length - 1] === '(') ||
      (s[i] === '}' && stack[stack.length - 1] === '{') ||
      (s[i] === ']' && stack[stack.length - 1] === '[')
    ) {
      stack.pop()
    } else {
      stack.push(s[i])
    }
  }
  return stack.length === 0
}

2. 删除最外层的括号

有效括号字符串为空 ""、"(" + A + ")" 或 A + B ,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。例如,"","()","(())()" 和 "(()(()))" 都是有效的括号字符串。如果有效字符串 s 非空,且不存在将其拆分为 s = A + B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。对 s 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 s 。

这类题型基本都是的使用。

  • 扫描字符串,判断当前位置是否为")"
    • 是,栈顶肯定是他对应的"("
    • 否则就是"(",推入栈中

这里需要注意的是,为了让结果字符串满足条件,需要提前将"("加入结果字符串中;否则容易将类似((()))这样的三层原语处理成()(),而非想要的(())

function removeOuterParentheses(s: string): string {
  const stack = []
  let target = ''
  for (let i = 0; i < s.length; i++) {
    if (s[i] === ')') {
      stack.pop()
      // 如果不是最外层的),收集结果
      if (stack.length !== 0) {
        target += s[i]
      }
    } else {
      // 提前收集结果
      if (stack.length !== 0) {
        target += s[i]
      }
      stack.push(s[i])
    }
  }
  return target
}