括号深度检测是编程面试和算法练习中的经典问题,主要考察对栈数据结构的理解和字符串处理能力。给定一个仅包含'('和')'的字符串,我们需要计算其中嵌套括号的最大深度。例如字符串"(()())"的最大深度是2,而"((()))"的最大深度是3。
这个问题看似简单,但涉及多个编程语言中字符串操作、栈实现等基础知识点。不同语言在处理字符串遍历、栈操作时有各自的特点,这也是为什么同时用Java、JavaScript和Python三种语言实现很有意义——可以对比不同语言的特性。
解决这个问题最直观的方法是使用栈数据结构:
这种方法时间复杂度O(n),空间复杂度O(n),是最直接的解决方案。
实际上可以进一步优化空间复杂度到O(1),因为我们只需要知道当前深度,不需要保存所有括号:
java复制public int maxDepth(String s) {
int max = 0;
Deque<Character> stack = new ArrayDeque<>();
for (char c : s.toCharArray()) {
if (c == '(') {
stack.push(c);
max = Math.max(max, stack.size());
} else if (c == ')') {
stack.pop();
}
}
return max;
}
java复制public int maxDepth(String s) {
int current = 0, max = 0;
for (char c : s.toCharArray()) {
if (c == '(') {
current++;
max = Math.max(max, current);
} else if (c == ')') {
current--;
if (current < 0) return -1; // 不匹配
}
}
return current == 0 ? max : -1;
}
注意:Java中使用Deque而不是Stack类,因为Stack是线程安全的,性能较差。ArrayDeque是更好的选择。
javascript复制function maxDepth(s) {
let max = 0, stack = [];
for (let c of s) {
if (c === '(') {
stack.push(c);
max = Math.max(max, stack.length);
} else if (c === ')') {
stack.pop();
}
}
return max;
}
javascript复制function maxDepth(s) {
let current = 0, max = 0;
for (let c of s) {
if (c === '(') {
current++;
max = Math.max(max, current);
} else if (c === ')') {
current--;
if (current < 0) return -1;
}
}
return current === 0 ? max : -1;
}
提示:现代JavaScript中推荐使用for...of遍历字符串,而不是传统的for循环。
python复制def max_depth(s: str) -> int:
max_depth = 0
stack = []
for c in s:
if c == '(':
stack.append(c)
max_depth = max(max_depth, len(stack))
elif c == ')':
stack.pop()
return max_depth
python复制def max_depth(s: str) -> int:
current = max_depth = 0
for c in s:
if c == '(':
current += 1
max_depth = max(max_depth, current)
elif c == ')':
current -= 1
if current < 0:
return -1
return max_depth if current == 0 else -1
注意:Python中列表的append/pop操作都是O(1)时间复杂度,非常适合实现栈。
| 输入 | 预期输出 | 说明 |
|---|---|---|
| "" | 0 | 空字符串 |
| "()" | 1 | 单层括号 |
| "(()())" | 2 | 多层嵌套 |
| "((()))" | 3 | 最大深度 |
| "(()" | -1 | 不匹配 |
| ")(" | -1 | 不匹配 |
实际应用中可能还需要考虑:
这些变种问题可以在基础解法上扩展:
python复制def max_depth_mixed(s: str) -> int:
pairs = {'(': ')', '[': ']', '{': '}'}
stack = []
max_depth = 0
for c in s:
if c in pairs:
stack.append(c)
max_depth = max(max_depth, len(stack))
elif c in pairs.values():
if not stack or pairs[stack[-1]] != c:
return -1
stack.pop()
return max_depth if not stack else -1
两种方法的时间复杂度都是O(n),都需要遍历整个字符串一次。
| 方法 | 空间复杂度 | 适用场景 |
|---|---|---|
| 栈实现 | O(n) | 代码直观,易于理解 |
| 计数器 | O(1) | 内存敏感场景 |
| 语言 | 字符串遍历 | 栈实现 | 特点 |
|---|---|---|---|
| Java | toCharArray() | Deque | 类型安全,性能好 |
| JavaScript | for...of | Array | 灵活,动态类型 |
| Python | 直接迭代 | list | 简洁,内置方法多 |
括号深度计算在实际开发中有多种应用:
例如,在代码编辑器实现语法高亮时,需要实时计算括号深度来确定着色规则:
javascript复制// 实时计算光标位置的括号深度
editor.on('cursorChange', () => {
const text = editor.getTextBeforeCursor();
let depth = 0;
for (let c of text) {
if (c === '(') depth++;
else if (c === ')') depth--;
}
updateHighlighting(depth);
});
例如在Python中添加调试打印:
python复制def max_depth(s):
current = max_depth = 0
for i, c in enumerate(s):
if c == '(':
current += 1
max_depth = max(max_depth, current)
elif c == ')':
current -= 1
if current < 0:
return -1
print(f"pos {i}: char '{c}', current={current}, max={max_depth}")
return max_depth if current == 0 else -1
通过三种语言的实现,我们可以观察到:
对于这个问题,O(1)空间的解法明显更优。但在实际工程中:
这些问题都可以基于类似的栈或计数器方法解决,但各有不同的难点和技巧。