我们遍历给定的字符串 s。当我们遇到一个左括号时,我们会期望在后续的遍历中,有一个相同类型的右括号将其闭合。由于后遇到的左括号要先闭合,因此我们不难想到该题可以使用数据结构栈
所以我们可以将这个左括号放入栈顶
当我们遇到一个右括号时,我们需要将一个相同类型的左括号闭合。此时,我们可以取出栈顶的左括号并判断它们是否是相同类型的括号。如果不是相同的类型,或者栈中并没有左括号,那么字符串 s 无效,返回False 否则继续入栈,最后判断是否所有的括号都被消除了即可(即判断是否栈空)
代码实现如下
class Solution {
public:bool isValid(string s) {
stack<char>st;
int len = s.length();
if (len % 2 != 0) return false;
st.push(s[0]);
for (int i = 1; i < len; i++)
{
if (!st.empty())
{
if (st.top() == '(' && s[i] == ')') st.pop();
else if (st.top() == '[' && s[i] == ']') st.pop();
else if (st.top() == '{' && s[i] == '}') st.pop();
else st.push(s[i]);
}
else st.push(s[i]);
}
if (st.empty()) return true;
return false;
}
};
下面这个代码与上面思路一致,只不过添加了一个函数用于配对括号
class Solution {
public:
char getleft(char r)//配对
{
if (r == ')') return '(';
else if (r == ']') return '[';
return '{';
}
bool isValid(string s) {
stack<char>st;
int len = s.length();
if (len % 2 != 0) return false;//排除奇数
for (int i = 0; i < len; i++)
{
if (s[i] == '(' || s[i] == '[' || s[i] == '{')//遇到左括号入栈
{
st.push(s[i]);
}
else
{
if (!st.empty() && getleft(s[i]) == st.top())//栈非空且此时的右括号与之匹配
{
st.pop();
}
else//否则继续入栈
{
st.push(s[i]);
}
}
}
if (st.empty())return true;//判断是否全部消除
return false;
}
};