「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」。
题目简述
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
先来一道简单的
假设只给你一个包括'(',')'的字符串,判断字符串是否有效,你要怎么处理。(不用栈呢?)
思路分析
我们可以得到下述分析
- 在任意一位置上,左括号 〉= 右括号
- 在最后位置上,左括号 === 右括号
- 在程序中只记录左数和右数即可
代码实现
var isVaild = function(s) {
let lnum = 0, rnum = 0;
const len = s.length;
for(let i = 0; i < len; i++) {
switch(s[i]) {
case "(":
++lnum;
break;
case ")":
++rnum;
break;
default:
return false;
}
if (lnume >= rnume) continue;
return false;
}
return lnum === rnum;
}
继续深入
所以一定要用两个变量来存储数量么?还能不能继续处理
思路分析
- l - r >= 0 差值任意位置均应该大于等于0
- 记录一个变量 左边 + 1,右边 -1
var isVaild = function(s) {
let lnum = 0;
const len = s.length;
for(let i = 0; i < len; i++) {
switch(s[i]) {
case "(":
++lnum;
break;
case ")":
--lnum;
break;
default:
return false;
}
if (lnume >= 0) continue;
return false;
}
return lnum === 0;
}
思考
我们获得了怎样的思考方式?
- 1、+1可以为“进”, -1可以为“出”
- 2、一对括号可以等价为一个完整的事件
- 3、(())可以看作事件与事件之间的完全包含关系
- 4、由括号的等价变换可以得到一个全新的数据结构
我们可以得出栈的一句话介绍:栈,可以用来处理具有“完全包含”关系的问题
横向思考,我们常见的完全包含关系还有,函数递归、二叉树
函数递归的调用一般是完全包含关系(函数调用关系)
二叉树可以分开分析,树形节点代表集合,子节点代表子集
1
/ \
2 3
--------------
(()())
即 1、2、2、3、3、1
即 概念泛化
思路描述
回归主题,接下来继续来解决这道题
使用栈的思维来解决这道题
想要了解一下栈???点击这里直达
- 先分析边界值,要求括号两两匹配,因此边界值为,传入字符串且字符串长度为单数时一定无效
- 遇见左括号压栈,遇见右括号则将上一个压栈出栈对比,如果是对应的左括号,则匹配成功,继续进行下一个操作
- 最终对比完成后,栈中没有值则有效,栈中有值则无效
- 对比中如果出现无法比对,压栈与出栈匹配失败,此字符串则无效(题目要求有效字符串必须满足正确顺序)
代码实现
var isValid = function (s) {
const map = new Map([
["(", ")"],
["[", "]"],
["{", "}"]
]);
const arr = s.split("");
const len = arr.length;
const stack = [];
if (len <= 1) return false;
for (let i = 0; i < len; i++) {
if (map.has(arr[i])) {
stack.unshift(arr[i]);
} else {
const left = stack[0];
if (map.get(left) === arr[i]) {
stack.shift();
} else {
return false;
}
}
if (i === len - 1 && stack.length === 0) return true;
if (i === len - 1 && stack.length != 0) return false;
}
};