1.题目

【LeetCode20】有效的括号(栈)_后进先出


【LeetCode20】有效的括号(栈)_字符串_02

2.思路

对给定的字符串进行遍历,当遇到一个左括号时,后面需要有一个相同类型的括号与其匹配,并且后遇到的左括号要先匹配,所以可以使用一个栈(先进后出,后进先出)。

遍历字符串:
(1)如果当前字符为左半边括号时,则压入栈中;
(2)如果为右半边括号时:
——若此时栈空则返回false;
——若当前遍历到的元素和栈顶元素恰好匹配成功则完成一个匹配的小目标(只有全部遍历完栈为空才能够返回​​​true​​​),所以这里有三个判断是返回​​false​​的,最后记得弹栈(才能继续下一个匹配小目标)。

注意:

有效字符串的长度一定为偶数——如果字符串的长度为奇数,可以直接返回false,省去后续的遍历判断过程。

3.代码

class Solution {
public:
bool isValid(string s) {
if(s.size()%2==1){//若为符号数为奇数则为false
return false;
}
stack<char>zhan;
for(int c=0;c<s.size();c++){//遍历一遍字符串的每个符号
if(s[c]=='('||s[c]=='['||s[c]=='{')
zhan.push(s[c]);
else{
if(zhan.empty())
return false;
if(s[c]==')'&&zhan.top()!='(')
return false;
if(s[c]==']'&&zhan.top()!='[')
return false;
if(s[c]=='}'&&zhan.top()!='{')
return false;
zhan.pop();
}
}
return zhan.empty();//判断最后栈是否为空
}
};

4.注意

(1)​​for (char c : s)​​​会复制一个s字符串再进行遍历操作,而使用​​for(char& c:s)​​时直接引用原来字符串进行遍历操作——由于复制一个字符串花费了时间,所以用前者的时间开销更多。
(2)以下是官方题解

class Solution {
public:
bool isValid(string s) {
int n = s.size();
if (n % 2 == 1) {
return false;
}

unordered_map<char, char> pairs = {
{')', '('},
{']', '['},
{'}', '{'}
};
stack<char> stk;
for (char ch: s) {
if (pairs.count(ch)) {
if (stk.empty() || stk.top() != pairs[ch]) {
return false;
}
stk.pop();
}
else {
stk.push(ch);
}
}
return stk.empty();
}
};