leetcode热题——有效的括号

有效的括号

题目描述

给定一个只包含 '(', ')', '{', '}', '[', ']' 的字符串,判断是否每个左括号都能被正确的右括号闭合,并且顺序正确。

例如:

输入 输出 解释
"()" true 成对
"()[]{}" true 成对,顺序正确
"(]" false 括号类型不匹配
"([)]" false 顺序不正确
"{[]}" true 成对嵌套

解题思路

这道题是使用栈解决的经典问题。

为什么可以用栈来做?

栈是一种后进先出(LIFO)的数据结构,非常适合处理成对出现且嵌套结构的问题。

想象如下字符串:

复制代码
"{ [ ( ) ] }"

从左往右处理:

  • 遇到左括号时就压入栈。
  • 遇到右括号时,从栈顶取出最近的左括号,检查是否与当前右括号匹配。
  • 匹配则继续,不匹配则返回 false。

以字符串 "{(){[]}}" 为例: 步骤如下:

i 当前字符 栈操作 栈状态 说明
0 { 入栈 { 左括号入栈
1 ( 入栈 { ( 左括号入栈
2 ) 匹配 & 出栈 { )( 成功匹配
3 { 入栈 { { 左括号入栈
4 [ 入栈 { { [ 左括号入栈
5 ] 匹配 & 出栈 { { ][ 成功匹配
6 } 匹配 & 出栈 { }{ 成功匹配
7 } 匹配 & 出栈 }{ 成功匹配

C++ 代码实现

cpp 复制代码
bool isValid(string s) {
    stack<char> stk;
    for (char ch : s) {
        // 左括号,压入栈
        if (ch == '(' || ch == '{' || ch == '[')
            stk.push(ch);
        else {
            // 遇到右括号,栈必须非空
            if (stk.empty()) return false;
            char top = stk.top();
            // 判断是否匹配
            if ((ch == ')' && top != '(') ||
                (ch == '}' && top != '{') ||
                (ch == ']' && top != '['))
                return false;
            stk.pop(); // 匹配成功,弹出
        }
    }
    // 如果所有括号都匹配,栈应为空
    return stk.empty();
}

复杂度分析

时间复杂度:O(n),只遍历一次字符串

空间复杂度:O(n),最坏情况下栈中存放所有左括号

代码优化

优化一:

如果字符串长度是奇数(n % 2 == 1),直接返回 false,因为括号必须成对出现,不可能匹配成功。

cpp 复制代码
        int n = s.size();
        if (n % 2 == 1) {
            return false;
        }

优化二:

定义一个哈希表 pairs,用于映射每个右括号对应的左括号。

cpp 复制代码
        unordered_map<char, char> pairs = {
            {')', '('},
            {']', '['},
            {'}', '{'}
        };

用哈希表 unordered_map 映射右括号对应的左括号,方便查找。而且可以提高代码的可扩展性,逻辑更清晰。

C++ 代码实现

cpp 复制代码
class Solution {
public:
    // 判断输入字符串中的括号是否成对匹配
    bool isValid(string s) {
        int n = s.size();
        
        // 若长度为奇数,不可能完全配对,直接返回 false
        if (n % 2 == 1) {
            return false;
        }

        // 定义右括号到左括号的映射关系
        unordered_map<char, char> pairs = {
            {')', '('},
            {']', '['},
            {'}', '{'}
        };

        stack<char> stk; // 用栈来存储尚未匹配的左括号

        // 遍历字符串中的每一个字符
        for (char ch : s) {
            // 如果是右括号
            if (pairs.count(ch)) {
                // 栈为空或栈顶不是对应的左括号,说明匹配失败
                if (stk.empty() || stk.top() != pairs[ch]) {
                    return false;
                }
                stk.pop(); // 匹配成功,弹出左括号
            } else {
                // 是左括号,入栈
                stk.push(ch);
            }
        }

        // 最终栈为空,说明所有括号都匹配成功
        return stk.empty();
    }
};
相关推荐
草履虫建模7 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq10 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq10 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
爱吃rabbit的mq11 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
(❁´◡`❁)Jimmy(❁´◡`❁)11 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi12 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
不能隔夜的咖喱12 小时前
牛客网刷题(2)
java·开发语言·算法
VT.馒头12 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
进击的小头12 小时前
实战案例:51单片机低功耗场景下的简易滤波实现
c语言·单片机·算法·51单片机
咖丨喱14 小时前
IP校验和算法解析与实现
网络·tcp/ip·算法