- ♂️ 作者:海码007
- 专栏:算法专栏
- 标题:【Hot 100】20. 有效的括号
- ❣️ 寄语:书到用时方恨少,事非经过不知难!
- 题目链接:
- 做题状态:
主要就是理解左右括号的配对原理。遍历到左括号时直接入栈就行,遍历到右括号时要判断栈顶元素是否是对应的左括号,如果是的话就可以消除(换句话就是出栈)。
class Solution {
public:
bool isValid(string s) {
stack<char> st;
st.push(s[0]);
for (int i = 1; i < s.size(); ++i)
{
// 分三种情况讨论
if (s[i] == ')')
{
if (st.empty()) return false; // 如果栈为空直接返回
if (st.top() == '(')
{
st.pop();
continue;
}
st.push(s[i]);
}
else if (s[i] == '}')
{
if (st.empty()) return false; // 如果栈为空直接返回
if (st.top() == '{')
{
st.pop();
continue;
}
st.push(s[i]);
}
else if (s[i] == ']')
{
if (st.empty()) return false; // 如果栈为空直接返回
if (st.top() == '[')
{
st.pop();
continue;
}
st.push(s[i]);
}
else
{
// 如果是左括号则直接入栈
st.push(s[i]);
}
}
return st.empty();
}
};
下面是一些具体的建议和优化:
1. 初始栈的入栈操作:
你的代码中在一开始就将s[0]
元素压入栈,这在某些情况下会导致不必要的处理,尤其是当字符串的第一个字符就是右括号时,可以直接返回false
。
2. 优化右括号的处理:
当遇到右括号时,你可以首先检查栈是否为空。如果为空,直接返回false
,否则你再检查栈顶是否是匹配的左括号。
3. 简化代码逻辑:
可以通过使用一个映射表来简化左右括号的匹配判断,从而避免重复代码。这样可以提高代码的可维护性。
4. 修复逻辑:
在你的代码中,遇到右括号时会在else
语句中将右括号再次压栈,这不必要且会导致栈中的元素不对,应该改成在判断不匹配时返回false
,而不是将不匹配的右括号压入栈。
class Solution {
public:
bool isValid(string s) {
stack<char> st;
// 这个匹配是通过右括号查找左括号的,别搞错了。
unordered_map<char, char> match = { {')', '('}, {'}', '{'}, {']', '['} };
for (char c : s)
{
if (match.count(c))
{
// 遇到右括号
// 如果栈为空或者没有匹配的左括号时直接返回false
if ( st.empty() || st.top() != match[c] ) return false;
// 如果遇到了对于的左括号,则弹出栈
st.pop();
}
else
{
// 遇到左括号就插入
st.push(c);
}
}
return st.empty();
}
};
unordered_map
来简化匹配操作,避免了重复的if
语句。true
,否则返回false
。这个版本的代码更加简洁、可读性更强,同时避免了冗余的判断和操作。