题目描述
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
解题思路:
利用栈的思想,先入后出。
JavaScript虽然没有栈,但是其数组可以用作栈来存放。
因此,可以遍历数组,遇到左括号入栈(新建数组存放),遇到右括号,与栈顶匹配。若类型匹配,使其出栈,对比下一个右括号与栈顶元素。直到新建数组元素为空或不匹配输出false。
注释
- 判断数组是否为 空 或 奇数,若有,则跳出直接输出 false。
- 遍历数组,若遇到 左括号,入栈(push)。遇到右括号,则先与栈顶匹配,若类型匹配,则出栈。若不匹配,直接 false。
- 判断 栈是否已空。
var isValid = function(s) {
// 1.判断数组是否为 空 或 奇数,若有,则跳出直接输出 false。
const length = s.length
if (!s || length % 2 === 1) {
return false
}
// 2.遍历数组,若遇到 左括号,入栈(push)。遇到右括号,则先与栈顶匹配,若类型匹配,则出栈。若不匹配,直接 false。
const stack = []
for ( let i = 0; i < length; i += 1) {
const c = s[i]
if (c === '(' || c === '{' || c === '[') {
stack.push(c)
} else {
const t = stack[stack.length - 1]
if(
(t === '(' && c === ')') ||
(t === '{' && c === '}') ||
(t === '[' && c === ']')
) {
stack.pop()
} else {
return false
}
}
}
// 3.判断 栈是否已空。
return stack.length === 0 ? true : false
};
改进 与 思考
第1步
“1.判断数组是否为空” 时,本写作
if (s === [] || length % 2 === 1)
后,也写作
if (!s || length % 2 === 1)
注意:
-
取栈顶元素之前,应该先判断栈是否为空
-
考虑输入为“]”的情况。此时会取到索引为-1的值。在JS中为undefined,但在其它语言中可能报错
第2步
“2.遍历数组,若遇到 左括号,入栈(push)。遇到右括号,则先与栈顶匹配,若类型匹配,则出栈。”
此步骤也可用 switch / case 方法,或者 map 方法。
具体操作步骤如下:
switch / case 方法
for(let item of s){
switch(item){
case "{":
case "[":
case "(":
stack.push(item);
break;
case "}":
if(stack.pop() !== "{") return false;
break;
case "]":
if(stack.pop() !== "[") return false;
break;
case ")":
if(stack.pop() !== "(") return false;
break;
}
}
map 方法 (涉及 算法-字典)
let map = new Map([[')', '('], [']', '['], ['}', '{']]);
let stack = [];
for(let i of s){
if (map.get(i)) {
if (stack[stack.length - 1] !== map.get(i)) return false;
else stack.pop();
} else {
stack.push(i);
}
}
第3步判断
“3.判断栈是否已空” 时,本来写作
if (stack.length === 0) { return true }
后,也可写作
return stack.length === 0
也可写作三元表达式
return stack.length === 0 ? true : false