持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
题目描述:
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
输入: s = "()"
输出: true
解题思路:
-
字符串为有效的括号,则长度一定是偶数
-
遍历字符串,遇到左括号就存储起来;遇到后面的右括号就检查是否可以与最后存储的左括号相匹配,如果可以匹配,就移除出去;遍历完所有括号,字符串就为空。这种思考过程就与栈数据结构先入后出的特点一致
-
因此准备一个栈存放括号对,遍历字符串的时候,遇到左括号就入栈,遇到右括号则判断右括号是否能和栈顶元素匹配,如果不匹配,直接return false(不是有效的括号),如果匹配,就把匹配的括号出栈
-
在循环结束的时候,判断栈是否为空,如果为空,则是有效括号,反之不是
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
const len = s.length;
//字符串长度为奇数,直接返回
if(len % 2 === 1) return false;
const pairs = new Map([
[')', '('], //因为需要判断字符串的右括号是否匹配左括号,因此需要右括号作为键值(key)
[']', '['],
['}', '{']
])
const stack = [] //创建一个栈
for(let item of s){
// 如果item为右括号,判断右括号是否能和栈顶元素匹配,反之,把左括号存入栈中
if(pairs.has(item)){
//如果右括号不能和栈顶元素匹配,直接返回;如果匹配,就把匹配的括号删除(相当于删除数组最后一个元素)
if(!stack.length || stack[stack.length - 1] !== pairs.get(item)){
return false;
}
stack.pop()
}else{
stack.push(item) //遇到左括号入栈
}
}
return !stack.length;//循环结束的时候,判断栈是否为空
};
注:此题解法中关于map的相关知识可以阅读这一篇文章:【算法实战之力扣刷题】两数之和
扩展:for...of 循环
for...of循环是ES6的语法,可以遍历 Arrays(数组), Strings(字符串), 类似数组的对象(比如arguments对象、DOM 对象),可迭代的对象(Map(映射), Set(集合))
for...of循环,遍历获得键值(value);for...in循环,遍历获得键名(key)
const array = ['西瓜', '桃子', '樱桃'];
const string = '[{}]';
const map = new Map([
['one', 1],
['two', 2]
]);
//遍历数组
for (let item of array) {
console.log(item)
// 西瓜
// 桃子
// 樱桃
}
for (let item in array) {
console.log(item)
// 0
// 1
// 2
}
//遍历字符串
for (let value of string) {
console.log(value)
// [
// {
// }
// ]
}
// 遍历map
// 每次循环都会返回一个数组[key,value],使用解构表达式const [number,name]立即对这对数组进行解构。
for (const [name, number] of map) {
console.log(name,number)
// one 1
// two 2
}
注:for…of循环不能循环普通的对象,推荐循环遍历普通对象的属性时使用for…in循环