括号匹配
题目
一个字符串内部可能包含 { } ( ) [ ] 三种括号,判断该字符串是否是括号匹配的。
如 (a{b}c) 就是匹配的, {a(b 和 {a(b}c) 就是不匹配的。
栈 Stack
该题目的考察目的很明确 —— 栈
栈,先进后出,基本的 API
- push
- pop
- length
和栈相关的数据结构(后面讲)
- 队列,先进先出
- 堆,如常说的“堆栈模型”
逻辑结构和物理结构
栈和数组有什么区别?—— 没有可比性,两者不一个级别。就像:房子和石头有什么区别?
栈是一种逻辑结构,一种理论模型,它可以脱离编程语言单独讲。
数组是一种物理结构,代码的实现,不同的语言,数组语法是不一样的。
栈可以用数组来表达,也可以用链表来表达,也可以自定义 class MyStack {...} 自己实现…
在 JS 中,栈一般情况下用数组实现。
思路
- 遇到左括号
{ ( [则压栈 - 遇到右括号
} ) ]则判断栈顶,相同的则出栈 - 最后判断栈 length 是否为 0
答案
普通解法
/**
* 判断左右括号是否匹配
* @param left 左括号
* @param right 右括号
*/
function isMatch(left: string, right: string): boolean {
if (left === '{' && right === '}') return true
if (left === '[' && right === ']') return true
if (left === '(' && right === ')') return true
return false
}
/**
* 判断是否括号匹配
* @param str str
*/
export function matchBracket(str: string): boolean {
const length = str.length
if (length === 0) return true
const stack = []
const leftSymbols = '{[('
const rightSymbols = '}])'
for (let i = 0; i < length; i++) {
const s = str[i]
if (leftSymbols.includes(s)) {
// 左括号,压栈
stack.push(s)
} else if (rightSymbols.includes(s)) {
// 右括号,判断栈顶(是否出栈)
const top = stack[stack.length - 1]
if (isMatch(top, s)) {
stack.pop()
} else {
return false
}
}
}
return stack.length === 0
}
ES6解法
使用MAP数据结构优化代码逻辑,减少代码量。对应力扣:20. 有效的括号 - 力扣(LeetCode) (leetcode-cn.com)
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
if(s.length % 2 === 1) return false // 优化,如果为奇数则不符合要求
const stack = []
const matchString = new Map([
[')', '('],
[']', '['],
['}', '{']
])
for(let str of s) {
const top = stack[stack.length - 1]
if(matchString.has(str)) {
if(matchString.get(str) === top) {
stack.pop()
} else {
return false
}
} else {
stack.push(str)
}
}
return stack.length === 0
};
划重点
- 栈
- 逻辑结构和物理结构