问题:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
3.每个右括号都有一个对应的相同类型的左括号。
虽然题目要求用栈实现,作者首先不考虑这个要求,优先写出答案。分析问题可知,本题要求为判断给定字符串是否有效。字符串有效条件有3个,第一个是对同种类型括号数目和顺序的要求。第二个是对不同类型括号顺序的要求,假设"(“等级为1,”[“等级为2,等级低的不可以包住等级高的,即”([])"无效。第三个要求同第一个。(从右括号反着要求过去)(这题不需要考虑括号等级,不过留着给读者看一下思路,写了不想再删了…)
题目类型:判断、遍历、字符匹配。
处理第一个要求,先只考虑一种类型(此处为小括号),从左到右遍历字符串(解决对于顺序的要求),有"(“就+1,有”)"-1,若中途统计数小于0时则前半部分右括号数目多于左括号,不符合对于顺序的要求,若最后统计数大于0则不符合对于数目的要求。(左括号多余右括号)总结就是统计数一直大于等于0且最后等于0。
处理第二个要求,对不同括号进行分级,初始等级为4,“{”等级为3,"[“为2,”("为1。当遇到右括号时,它会与最新左括号匹配,故右括号应该等于最新左括号等级,也就是所处当前等级,然后因为匹配成功而退出当前等级返回上一等级。(由于本题没有要求小括号不能装大括号,不分等级直接用字符去匹配也是可以的,如果需要考虑等级规则会再复杂一点)
class Solution {
public:
bool isValid(string s) {
int small, medium, large;
small = medium = large = 0;
int level[10000] = {0}; //using level to handle the rank of the bracket
int levelFlag = 0;
for (int i = 0; i < s.length(); i++){
if(s[i] == '('){
small += 1;//handle require 1
levelFlag+=1;//handle reuqire 2
level[levelFlag] = 1;
}
else if(s[i] == ')'){
small -= 1; //handle require 1
if(small < 0)
return false;
if(level[levelFlag] == 1){//handle require 2
levelFlag--;
}else
return false; //no match
}
else if(s[i] == '['){
medium += 1;
levelFlag+=1;
level[levelFlag] = 2;
}
else if(s[i] == ']'){
medium -= 1;
if(medium < 0)
return false;
if(level[levelFlag] == 2)
levelFlag--;
else
return false;
}
else if(s[i] == '{')
{
large += 1;
levelFlag+=1;
level[levelFlag] = 3;
}
else{
large -= 1;
if(large < 0)
return false;
if(level[levelFlag] == 3)
levelFlag--;
else
return false;
}
}
if(large > 0 || medium > 0 || small > 0 )
return false;
return true;
}
};
下一节转为用栈实现。实际上已经挺明显了,我们只在数组的尾端进行操作,完美符合了栈的特性。
题目力扣链接:https://leetcode.cn/problems/valid-parentheses/