算法题 有效的括号

算法题:判断有效括号

20. 有效的括号

问题描述

给定一个只包括 '('')''{''}''['']' 的字符串 s,判断字符串是否有效。有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

示例

示例 1:

	输入:s = "()"
	
	输出:true

示例 2:

	输入:s = "()[]{}"
	
	输出:true

示例 3:

	输入:s = "(]"
	
	输出:false

示例 4:

	输入:s = "([])"
	
	输出:true

算法思路

的经典应用

  1. 遍历字符串:处理每个字符
  2. 左括号入栈:遇到左括号 (, {, [ 时压入栈
  3. 右括号匹配:遇到右括号时:
    • 若栈为空 → 无效(没有匹配的左括号)
    • 弹出栈顶元素 → 检查是否匹配当前右括号
    • 不匹配 → 直接返回 false
  4. 最终检查:遍历结束后,栈必须为空(所有括号完成匹配)

代码实现

import java.util.Stack;

class Solution {
    /**
     * 判断括号字符串是否有效
     * 
     * @param s 输入字符串
     * @return 是否有效
     */
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        
        for (char c : s.toCharArray()) {
            // 情况1:遇到左括号 → 入栈
            if (c == '(' || c == '{' || c == '[') {
                stack.push(c);
            } 
            // 情况2:遇到右括号
            else {
                // 栈为空时遇到右括号 → 无效
                if (stack.isEmpty()) {
                    return false;
                }
                
                // 弹出栈顶元素并检查匹配
                char top = stack.pop();
                if (c == ')' && top != '(') {
                    return false;
                }
                if (c == '}' && top != '{') {
                    return false;
                }
                if (c == ']' && top != '[') {
                    return false;
                }
            }
        }
        
        // 最终栈必须为空(所有左括号已匹配)
        return stack.isEmpty();
    }
}

算法分析

  • 时间复杂度:O(n)
    只需遍历字符串一次,每个字符处理时间为 O(1)
  • 空间复杂度:O(n)
    栈的空间开销,最坏情况(全左括号)存储所有字符

算法过程

s = "[({}])"

  1. [ → 入栈(栈:[
  2. ( → 入栈(栈:[, (
  3. { → 入栈(栈:[, (, {
  4. } → 弹出 { → 匹配(栈:[, (
  5. ] → 弹出 (不匹配!返回 false

s = "{[]}"

  1. { → 入栈(栈:{
  2. [ → 入栈(栈:{, [
  3. ] → 弹出 [ → 匹配(栈:{
  4. } → 弹出 { → 匹配(栈空)
  5. 返回 true

边界条件处理

情况处理方式
单字符直接返回 false
右括号开头立即返回 false(栈空时遇到右括号)
左括号结尾最终检查栈非空 → 返回 false

测试用例

public static void main(String[] args) {
    Solution solution = new Solution();
    
    System.out.println(solution.isValid("()"));        // true
    System.out.println(solution.isValid("()[]{}"));    // true
    System.out.println(solution.isValid("(]"));        // false
    System.out.println(solution.isValid("([)]"));      // false
    System.out.println(solution.isValid("{[]}"));      // true
    System.out.println(solution.isValid(""));          // true (边界:空字符串)
    System.out.println(solution.isValid("["));         // false (边界:单左括号)
    System.out.println(solution.isValid("]"));         // false (边界:单右括号)
    System.out.println(solution.isValid("{[()]}"));    // true (嵌套括号)
}

关键点

  1. 栈的核心作用

    • 按顺序存储未匹配的左括号
    • 保证最近打开的括号最先闭合(LIFO特性)
  2. 匹配逻辑

    if (c == ')' && top != '(') return false;  // 小括号匹配
    if (c == '}' && top != '{') return false;  // 花括号匹配
    if (c == ']' && top != '[') return false;  // 方括号匹配
    
  3. 两个终结条件

    • 处理右括号时栈空 → 无效
    • 遍历结束栈非空 → 无效
  4. 避免空栈异常

    if (stack.isEmpty()) return false; // 关键防御
    

常见问题

  1. 为什么用栈不用计数器?
    三种括号类型混合时,计数器无法检测顺序错误(如 ([)]

  2. 如何处理嵌套括号
    栈的 LIFO 特性天然支持嵌套结构(最近开括号必须最先闭合)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值