今天想睡觉了,写个简单的"栈"入门题换换脑袋就睡觉了,dp整理先欠着》
一.写题记录
20.有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
java
class Solution {
public boolean isValid(String s) {
// 获取字符串长度 O(1)
int n = s.length();
// 剪枝优化:有效括号字符串长度必须为偶数
// 如果长度为奇数,一定无法完全匹配,直接返回false
// 时间复杂度 O(1),空间复杂度 O(1)
if (n % 2 == 1) {
return false;
}
// 建立哈希映射:右括号 -> 对应的左括号
// 使用匿名内部类进行初始化,方便快速查找匹配关系
// 空间复杂度 O(|Σ|),其中 |Σ| = 3,即常数空间 O(1)
Map<Character, Character> pairs = new HashMap<Character, Character>() {{
put(')', '('); // 右圆括号对应左圆括号
put(']', '['); // 右方括号对应左方括号
put('}', '{'); // 右花括号对应左花括号
}};
// 使用双端队列作为栈结构
// Deque接口比Stack类更现代,LinkedList实现了Deque接口
// 栈用于存储等待匹配的左括号
// 空间复杂度 O(n),最坏情况下栈中存储 n/2 个元素
Deque<Character> stack = new LinkedList<Character>();
// 遍历字符串中的每一个字符
// 时间复杂度 O(n),需要遍历所有字符
for (int i = 0; i < n; i++) {
char ch = s.charAt(i);
// 判断当前字符是否为右括号(即是否在映射的键中)
// containsKey 操作时间复杂度 O(1)
if (pairs.containsKey(ch)) {
// 当前是右括号的情况
// 情况1:栈为空,说明没有左括号可以匹配 → 无效
// 情况2:栈顶元素(最近的左括号)与当前右括号不匹配 → 无效
// peek() 操作时间复杂度 O(1)
if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
return false; // 提前返回,时间复杂度 O(1)
}
// 匹配成功,弹出栈顶的左括号(表示这一对括号已处理)
// pop() 操作时间复杂度 O(1)
stack.pop();
} else {
// 当前是左括号的情况
// 将左括号压入栈中,等待后续的右括号来匹配
// push() 操作时间复杂度 O(1)
stack.push(ch);
}
}
// 遍历结束后,栈为空说明所有左括号都找到了匹配的右括号
// 栈不为空说明还有左括号未被匹配 → 无效
// isEmpty() 操作时间复杂度 O(1)
return stack.isEmpty();
}
}
// 总体复杂度分析:
// 时间复杂度:O(n) - 需要遍历整个字符串一次,每个字符操作都是 O(1)
// 空间复杂度:O(n) - 最坏情况下栈需要存储 n/2 个字符(全是左括号的情况)
// 其中 n 为字符串 s 的长度
二.思考(不成熟,供参考,欢迎指正)
(20)
Char=String.charAt(i)
java
Deque<Character> stack = new ArrayDeque<>(); // 推荐:创建栈
stack.push('('); // 入栈
char top = stack.peek(); // 查看栈顶(不移除)
char popped = stack.pop(); // 出栈(移除并返回)
boolean empty = stack.isEmpty(); // 判断是否为空
int size = stack.size(); // 获取栈大小
stack.clear(); // 清空栈
一些和d老师的请教记录
q1:Deque?
a1:Deque = Double Ended Queue(双端队列),是 Java 中一个非常重要的接口。
java
import java.util.*;
public class DequeExample {
public static void main(String[] args) {
// 创建双端队列
Deque<String> deque = new ArrayDeque<>();
// 作为栈使用(后进先出)
System.out.println("=== 作为栈使用 ===");
deque.push("第1个"); // 入栈
deque.push("第2个"); // 入栈
deque.push("第3个"); // 入栈
System.out.println("栈: " + deque); // [第3个, 第2个, 第1个]
System.out.println("栈顶: " + deque.peek()); // 第3个
System.out.println("出栈: " + deque.pop()); // 第3个
System.out.println("出栈后: " + deque); // [第2个, 第1个]
// 清空重新使用
deque.clear();
// 作为队列使用(先进先出)
System.out.println("\n=== 作为队列使用 ===");
deque.offer("第1个"); // 入队尾
deque.offer("第2个"); // 入队尾
deque.offer("第3个"); // 入队尾
System.out.println("队列: " + deque); // [第1个, 第2个, 第3个]
System.out.println("队首: " + deque.peek()); // 第1个
System.out.println("出队: " + deque.poll()); // 第1个
System.out.println("出队后: " + deque); // [第2个, 第3个]
}
}
致谢/参考资料:
尊敬的力扣老师和尊敬的Deepseek老师!
声明:
本文内容仅用于个人学习记录,不用于任何商业用途。部分代码、技术观点或示例可能来源于网络或其他公开资源,如有侵权,请联系我删除。