【路飞】验证栈序列&&有效的括号&&删除外层括号&&移除无效括号

241 阅读1分钟

记录5道算法题

验证栈序列

946. 验证栈序列 - 力扣(LeetCode) (leetcode-cn.com)


没太看懂这道题想干嘛,看题解好像是想依次推入 pushed,然后 popped 是推入之后的可能进行的弹栈操作记录。有可能是一次性推入全部,然后再弹。也可能是一边推入,一边弹出。 所以 popped 不一定是 pushed 的倒序。

那么就是检验 popped 的操作是否是合理的。能不能弹出想要的数字。

    function validateStackSequences(pushed, popped) {
        cosnt stack = []
        let index = 0
        
        const len = pushed.length
        for(let i = 0; i < len; i++) {
           // 模拟推入
            stack.push(pushed[i])
            // 假设这时发生了弹栈的操作,就一直弹
            while(index < len && popped[index] === stack[stack.length - 1]) {
                index++
                stack.pop()
            }
        }
        
        // 栈清空,说明操作匹配得上
        return stack.length === 0
    }

有效的括号

leetcode-cn.com/problems/va…


要求:

    * 一对括号 '(' ')' '{' '}' '[' ']', 进行匹配
    * 可以嵌套。但必须两两匹配,匹配返回 true

用栈就可以解决,类似模板解析的问题

    function isValid(s) {
        const stack = []
        const end = new Map([
          [')', '('],
          ['}', '{'],
          [']', '[']
        ])
        for (let i = 0; i < s.length; i++) {
          const ko = s[i]
          // 如果是闭合的括号
          if (end.has(ko)) {
            if (stack[stack.length - 1] === end.get(ko)) {
                // 和最近的括号匹配上
              stack.pop()
            } else {
                // ']' 这种情况时
              return false
            }
          } else {
            stack.push(ko)
          }
        }

        return stack.length === 0
    }

删除最外层的括号

1021. 删除最外层的括号 - 力扣(LeetCode) (leetcode-cn.com)


一开始想着用栈去解决,但是遇到了很多麻烦,例如多层嵌套的时候就会变得很复杂。但其实和栈没有太多关系。只是去掉外面一层的括号,哪怕里面嵌套再多也不用去管,可以原样输出。

所以只要标记出最外面一层的括号,其他直接输出就行。

    function removeOuterParentheses(s) {
        const stack = []
        const result = []
        let temp = ''
        for (let i = 0; i < s.length; i++) {
          const ko = s[i]
          if (ko === '(') {
              // 推入栈中,进行括号匹配
            stack.push(ko)
            // 标记第一个,如果向下执行就是拼接 temp
            if (stack.length === 1) {
              continue
            }
          }

          if (ko === ')') {
              // 弹出栈
            const a = stack.pop()
            // 当弹干净的时候就把 收集的 temp 存起来
            if (stack.length === 0) {
              result.push(temp)
              temp = ''
              continue
            }
          }
            
            // 拼接
          temp += ko
        }
        
        // 多个 去掉最外层的 temp 加起来
        return result.reduce((a, b) => a + b)
   }

移除无效括号

leetcode-cn.com/problems/mi…


要求:

    1. 用栈进行匹配,然后把不符合的字符替换掉就可以了
    2. 除了匹配不到的时候,把字符替换,同时把栈里面剩余的进行替换。
    function minRemoveToMakeValid(s) {
        const stack = []
        // 为了修改字符,先转成数组
        s = s.split('')
        for (let i = 0; i < s.length; i++) {
          const ko = s[i]
          if (ko === '(') {
              // 存放的是下标
            stack.push(i)
          } else if (ko === ')') {
            if (stack.length > 0) {
                // 匹配到了
              stack.pop()
            } else {
                // 没有匹配到的 标记一下 }}
              s[i] = '_'
            }
          }
        }
        
        // 因为可能有没有闭合的括号
        for (let i = 0; i < stack.length; i++) {
            // 栈中存放的是该字符所在的下标
          s[stack[i]] = '_'
        }
        
        return s.filter(_ => _ != '_').join('')
      }

结束