

🔥个人主页:北极的代码(欢迎来访)
🎬作者简介:java后端学习者
✨命运的结局尽可永在,不屈的挑战却不可须臾或缺!
前言:前天一次性做了好几道题目,但是没有时间发出来,今天一次性全发了吧,其实写着思路也是挺累的,还要再想一遍,不过可以提高熟练度。
摘要:
这篇文章讲解了如何用栈结构判断括号字符串的有效性。
题目要求判断包含三种括号(圆括号、方括号、花括号)的字符串是否有效,即左括号必须按正确顺序闭合。
通过示例详细分析了匹配过程:遇到左括号时将对应右括号压栈,遇到右括号时检查栈顶是否匹配。文章指出了三种失败情况(栈未空、栈为空或栈顶不匹配)和成功条件(遍历完栈为空),并给出了Java实现代码,使用Deque模拟栈操作。这种方法巧妙地通过预存对应右括号简化了匹配判断,时间复杂度为O(n)。
题目背景:20.有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 注意空字符串可被认为是有效字符串。
示例 1:
- 输入: "()"
- 输出: true
示例 2:
- 输入: "()[]{}"
- 输出: true
示例 3:
- 输入: "(]"
- 输出: false
示例 4:
- 输入: "([)]"
- 输出: false
示例 5:
- 输入: "{[]}"
- 输出: true
题目解析:
这道题目其实就是《数据结构与算法》一书中的例题,也是栈最常见的应用。
题意其实就像我们在写代码的过程中,要求括号的顺序是一样的,有左括号,相应的位置必须要有右括号。
如果还记得编译原理的话,编译器在 词法分析的过程中处理括号、花括号等这个符号的逻辑,也是使用了栈这种数据结构。
这里有一个很容易理解错的逻辑漏洞,不仅仅是判断一个左括号对应一个右括号,还要判断交叉嵌套问题。如果是([)]例如这样子
字符 操作 栈状态 '(' 左括号,入栈 [(] '[' 左括号,入栈 [ (, [ ] ')' 右括号,弹出 '[' → 不匹配 ❌ 返回 false 第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。
分析完之后,代码其实就比较好写了
具体的实现:
我们这里用的是比较巧妙的方法,当我们进栈的时候,先做判断,如果是左括号就往栈里放右括号,同理其他括号,这样遇到右括号时直接比较是否相等即可。
关于前面说的嵌套问题,我们这里给定一个判断条件,也就是查看栈顶的元素时候和要比较的右括号相等,相等则是相同类型的括号,匹配,否则返回false。
示例:
"([{}])"
步骤 字符 操作 栈状态(栈顶在右) 1 '(' 压对应的 )[)2 '[' 压对应的 ][), ]3 '{' 压对应的 }[), ], }4 '}' 遇到 },栈顶是}✅ 弹出[), ]5 ']' 遇到 ],栈顶是]✅ 弹出[)6 ')' 遇到 ),栈顶是)✅ 弹出[]遍历结束,栈为空 →
true示例:
"([)]"(错误情况)
步骤 字符 操作 栈状态 1 '(' 压 )[)2 '[' 压 ][), ]3 ')' 遇到 ),栈顶是]❌ 不匹配返回 false
题目答案:
java
class Solution {
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<>();
char ch;
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
//碰到左括号,就把相应的右括号入栈
if (ch == '(') {
deque.push(')');
}else if (ch == '{') {
deque.push('}');
}else if (ch == '[') {
deque.push(']');
} else if (deque.isEmpty() || deque.peek() != ch) {
return false;
}else {//如果是右括号判断是否和栈顶元素匹配
deque.pop();
}
}
//遍历结束,如果栈为空,则括号全部匹配
return deque.isEmpty();
}
}