题面
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 注意空字符串可被认为是有效字符串。
示例
示例 1:
- 输入: "()"
- 输出: true
示例 2:
- 输入: "()[]{}"
- 输出: true
示例 3:
- 输入: "(]"
- 输出: false
示例 4:
- 输入: "([)]"
- 输出: false
示例 5:
- 输入: "{[]}"
- 输出: true
解题思路
- 先判断字符串长度是否为偶数,不是偶数的话,可以直接返回false
- 由题可知:是两个元素的对应关系,因此可以用哈希映射来解决,那么此时就可以使用Map
- 分析可知:遇到的左括号压入栈顶,遇到右括号将栈中的左括号弹出来进行匹配。 匹配不成功:false 匹配成功:进入下一轮
- 直到整个字符串被比较完成,判断当前堆是否为空 非空:false 空:true
解题源码
- 首次源码
/**
* @param {string} s
* @return {boolean}
*/
/* 几种情况:
1. 左括号单身
2. 右括号单身
*/
var isValid = function (s) {
// 创建线性表,模仿栈
// 取出字符串开头判断是:左括号 还是 右括号
// 1.左括号:继续往里面找,直到找到最里面的左括号,同时将左括号压入栈顶
// 找到第一个右括号,弹出最里面的一个左括号,查看是否匹配
// 不匹配 false
// 匹配 true
// 如果 字符串还有右括号 ,此时栈里没有左括号 -> 右括号单身 false
// 如果 栈 还有左括号,此时字符串中没有 -> 左括号单身 false
// 2.右括号:false
/*
又可以改进的地方:长度为奇数的时候,直接返回false
*/
length = s.length;
if(length % 2 != 0){ // 优化
return false;
}
// 哈希映射
//声明一个map集合
var myMap = new Map([
[')','('],
['}','{'],
[']','[']
]);
// 定义一个栈: 栈相当于特殊的链表
var stk = [];
var rightKH = s.charAt(0);
// 对于string可以使用charAt()函数来获取当前的值
for(var i = 0; i < length; i++){
rightKH = s.charAt(i);
//如果是 左括号 一直找下去
if(rightKH == "(" || rightKH == "{" || rightKH == "["){
//将左括号 放入栈中
stk.push(rightKH);
}else {
var value = stk.pop();
// 当前为右括号 判断是否有与之相符的左括号
if(rightKH == ")"){
if(myMap.get(")") != value){
return false;
}
}else if(rightKH == "}"){
if(myMap.get("}") != value){
return false;
}
}else if(rightKH == "]"){
if(myMap.get("]") != value){
return false;
}
}
}
}
if(stk.length != 0){
return false;
}
return true;
};
/*
查询补充:
js中定义变量:const let var
1. const 定义的变量不可修改,必须初始化
2. let 定义的变量块级作用域,函数内部使用let定义后,对函数外部无影响
3. var定义的变量可以修改,如果不初始化会输出undefined,不会报错
*/
- 第二次源码
var isValid = function (s) {
length = s.length;
if(length % 2 != 0){
return false;
}
// 哈希映射
//声明一个map集合
var myMap = new Map([
[')','('],
['}','{'],
[']','[']
]);
// 定义一个栈: 栈相当于特殊的链表
var stk = [];
var rightKH = s.charAt(0);
// 对于string可以使用charAt()函数来获取当前的值
for(var i = 0; i < length; i++){
rightKH = s.charAt(i);
//如果是 左括号 一直找下去
if(rightKH == "(" || rightKH == "{" || rightKH == "["){
//将左括号 放入栈中
stk.push(rightKH);
}else {
var value = stk.pop();
// 当前为右括号 判断是否有与之相符的左括号
// if(rightKH == ")"){
// if(myMap.get(")") != value){
// return false;
// }
// }else if(rightKH == "}"){
// if(myMap.get("}") != value){
// return false;
// }
// }else if(rightKH == "]"){
// if(myMap.get("]") != value){
// return false;
// }
// }
//将上述替换为下面语句
if(myMap.get(rightKH) != value){
// console.log(myMap.get(rightKH));
return false;
}
}
}
if(stk.length != 0){
return false;
}
return true;
};
- 运行效率
注意
查询补充:js中定义变量:const let var
- const 定义的变量不可修改,必须初始化
- let 定义的变量块级作用域,函数内部使用let定义后,对函数外部无影响
- var定义的变量可以修改,如果不初始化会输出undefined,不会报错
代码优化
// 两个匹配问题,那么字符串长度一定是偶数
if(length % 2 != 0){ // 优化
return false;
}
代码出错点
// 判断栈是否为空
if(stk.length != 0){
return false;
}
return true;
学习Map
- 声明方式
var myMap = new Map([
[')','('],
['}','{'],
[']','[']
]);
- 通过key获取相应的value值
myMap.get(rightKH) -> value