携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情
题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
解题思路——抵消法
首先通过题目我们可以知道,如果给定的字符串是有效的,那么括号一定是成对存在的,每个类型的左括号对应一个各自类型的右括号,没有一个多余或缺少的。
拿字符串 ()[]{} 来说,我们可以先消除 (),然后消除 [],最后消除 {},最后字符串剩下了 "",消除的先后顺序不重要,只要能消完就说明字符串中各个类型的括号都是配对的。
那么我们就可以通过循环,不断消除各个类型的括号,直到 全部消除完 或 剩下几个单身括号。
我们都知道如果能消完的话,一次能消除两个括号,且最后剩余的是空字符串。那么对于一个长度为 n 的字符串 s,我们需要的循环次数为 n / 2,如果剩余字符串不是空串,说明不能两两配对完,否则说明该字符串是有效的。
题解
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
let cnt = s.length >> 1;
while(cnt--) {
if(s.includes('()')) {
s = s.replace('()', '');
} else if(s.includes('[]')) {
s = s.replace('[]', '');
} else if(s.includes('{}')) {
s = s.replace('{}','');
}
}
return s.length === 0;
};
解题思路——栈
相信大家都知道栈的特性了,就是后进先出。那么栈和今天的题目有什么关系呢?
本题只有在 左括号与同类型的右括号相遇 的时候,才能将这两个括号抵消,所以我们可以将所有未被抵消的括号都 存在一个栈 中,一旦当前遍历到的元素和栈顶的元素是 配对 的,那么就可以消除栈顶的元素,这么遍历到最后的话,如果字符串中的每个字符都是配对的,那么最后抵消完的字符串就是有效的(空串),否则就说明该字符串是无效的(非空串)。
题解
var isValid = function(s) {
const stack = [], mp = {
')': '(',
']': '[',
'}': '{'
};
for(let o of s) {
if(stack.length && stack[stack.length - 1] === mp[o]) { // 遇到结束符号
stack.pop();
continue;
}
stack.push(o);
}
return stack.length === 0;
};