首页 > 其他分享 >【练习】力扣热题100 有效的括号

【练习】力扣热题100 有效的括号

时间:2025-01-14 19:58:21浏览次数:3  
标签:pairs ch return stk 力扣 括号 false 100 热题

题目

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = “()”

输出:true

示例 2:

输入:s = “()[]{}”

输出:true

示例 3:

输入:s = “(]”

输出:false

示例 4:

输入:s = “([])”

输出:true

来源:力扣热题100 有效的括号


题解

class Solution {
public:
    bool isValid(string s) {
        int n = s.size();
        stack<char> st;
        for(int i = 0; i < n; i ++)
        {
            if(s[i] == '(' || s[i] == '[' || s[i] == '{')
                st.push(s[i]);
            else
            {
                if(st.empty())
                    return false;
                if(st.top() == '(' && s[i] != ')')
                    return false; 
                if(st.top() == '[' && s[i] != ']')
                    return false; 
                if(st.top() == '{' && s[i] != '}')
                    return false; 
                st.pop();
                if(st.empty() && i == n - 1)
                    return true;
            }
        }
        return false;
    }
};

题解(优化)

class Solution {
public:
    bool isValid(string s) {
        int n = s.size();
        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();
    }
};

以下是代码的详细分析:


pairs.count(ch) 的作用

  • pairs.count(ch) 是 C++ 中 unordered_map 的成员函数,用于检查键 ch 是否存在于哈希表 pairs 中。
  • 返回值:
    • 如果 chpairs 的键(即 ch 是右括号 )]}),则返回 1
    • 如果 ch 不是 pairs 的键(即 ch 是左括号或其他字符),则返回 0

代码逻辑分析:

  1. 检查字符串长度

    int n = s.size();
    if (n % 2 == 1) {
        return false;
    }
    
    • 如果字符串的长度是奇数,则括号一定无法完全匹配,直接返回 false
  2. 定义括号映射

    unordered_map<char, char> pairs = {
        {')', '('},
        {']', '['},
        {'}', '{'}
    };
    
    • 使用一个哈希表 pairs 来存储右括号和对应的左括号的映射关系。
    • 例如,')' 对应 '('']' 对应 '[''}' 对应 '{'
  3. 使用栈进行匹配

    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);
        }
    }
    
    • 遍历字符串中的每个字符:
      • 如果当前字符是右括号(即 pairs.count(ch) 为真):
        • 检查栈是否为空,或者栈顶元素是否与当前右括号对应的左括号匹配。
        • 如果不匹配,则返回 false
        • 如果匹配,则将栈顶元素弹出。
      • 如果当前字符是左括号,则将其压入栈中。
  4. 检查栈是否为空

    return stk.empty();
    
    • 如果栈为空,说明所有括号都匹配成功,返回 true
    • 如果栈不为空,说明有未匹配的左括号,返回 false

举例说明:

假设输入字符串为 s = "()[]{}",运行过程如下:

  1. 初始化

    • stk = [](空栈)。
  2. 遍历字符

    • ch = '(':是左括号,压入栈中。stk = ['(']
    • ch = ')':是右括号,检查栈顶元素 '(' 是否匹配。匹配,弹出栈顶元素。stk = []
    • ch = '[':是左括号,压入栈中。stk = ['[']
    • ch = ']':是右括号,检查栈顶元素 '[' 是否匹配。匹配,弹出栈顶元素。stk = []
    • ch = '{':是左括号,压入栈中。stk = ['{']
    • ch = '}':是右括号,检查栈顶元素 '{' 是否匹配。匹配,弹出栈顶元素。stk = []
  3. 最终检查

    • 栈为空,返回 true

时间复杂度:

  • O(n),其中 n 是字符串的长度。每个字符只会被压入栈和弹出栈一次。

空间复杂度:

  • O(n),在最坏情况下(例如全是左括号),栈的大小为 n/2

代码的改进建议:

  1. 使用数组代替哈希表

    • 由于括号字符的 ASCII 值是连续的,可以使用数组代替哈希表来存储映射关系,进一步提高性能。

    改进后的代码:

    class Solution {
    public:
        bool isValid(string s) {
            int n = s.size();
            if (n % 2 == 1) {
                return false;
            }
    
            char pairs[256] = {0}; // 初始化所有字符映射为 0
            pairs[')'] = '(';
            pairs[']'] = '[';
            pairs['}'] = '{';
    
            stack<char> stk;
            for (char ch: s) {
                if (pairs[ch]) {
                    if (stk.empty() || stk.top() != pairs[ch]) {
                        return false;
                    }
                    stk.pop();
                }
                else {
                    stk.push(ch);
                }
            }
            return stk.empty();
        }
    };
    

总结:

这段代码通过栈和哈希表的方法,高效地解决了括号匹配问题。它的时间复杂度为 O(n),空间复杂度为 O(n),并且能够处理各种边界情况。如果需要进一步优化,可以使用数组代替哈希表,或者添加更多的边界条件处理。

标签:pairs,ch,return,stk,力扣,括号,false,100,热题
From: https://blog.csdn.net/2402_86344613/article/details/145146208

相关文章

  • 华为OD E卷(100分)56-矩阵扩散
     前言    工作了十几年,从普通的研发工程师一路成长为研发经理、研发总监。临近40岁,本想辞职后换一个相对稳定的工作环境一直干到老,没想到离职后三个多月了还没找到工作,愁肠百结。为了让自己有点事情做,也算提高一下自己的编程能力,无聊之余打算用一些大厂的编程题练......
  • 3分钟搞懂Arrow Flight SQL,让数据传输提速100倍的秘密
    3分钟搞懂ArrowFlightSQL,让数据传输提速100倍的秘密数据传输提速100倍!如何做到100倍提升?让数据传输起飞!小结此时,数据分析师小华揉着发酸的眼睛,望着电脑屏幕发呆。他忍不住抱怨道:“这数据导出也太慢了吧!”是的,又一次等待MySQL协议传输大批量数据,这感觉像是用吸管......
  • 刷力扣的技巧:4 个步骤 7 个关键点,事半功倍,冲进大厂!
    最近好多人问我咋刷力扣呀,今天我就来给大家好好唠唠。我总结了7个要点和4个步骤,尤其是最后那提效4步骤,可太有用啦。大家一定要看到最后哦,记得点赞、收藏呀。要点一:别光追求刷题量,题解也得看咱好多同学呀,解开一道题就着急忙慌地去刷下一道,还把刷题数量当成衡量水平的唯一标......
  • HDLBits-Verilog:Counter 1000
    从1000Hz时钟中,得出一个1Hz信号,称为 OneHertz,该信号可用于驱动一组小时/分钟/秒计数器的启用信号,以创建数字挂钟。由于我们希望clock每秒计数一次,因此 OneHertz 信号必须每秒正好置位一个周期。使用modulo-10(BCD)计数器和尽可能少的其他门构建分频器。此外,还输出......
  • 利用CSS改变图片颜色的100种方法!
    https://juejin.cn/post/6844903682010513415前言“说到对图片进行处理,我们经常会想到PhotoShop这类的图像处理工具。作为前端开发者,我们经常会需要处理一些特效,例如根据不同的状态,让图标显示不同的颜色。或者是hover的时候,对图片的对比度,阴影进行处理。”你以为这些是经......
  • 力扣977(2)
    题目及暴力法解法在之前的这篇博客,想了解的可以移步到这里:力扣977题——有序数组的平方双指针法:因为暴力法的时间复杂度还是太高了,有O(nlogn)这么多,这次就使用双指针法只需要O(n):解题思路建了一个新数组a用来存放平方,新数组使用一个k指针指向数组的末尾;(这里数组可以随......
  • LeetCode 热题 HOT 100
    点个关注,不迷路!(╯▽╰)好香~~在学习过程中,借助一些优秀的工具可以极大地提升我们的学习效率。例如,使用LeetCode插件,它能够帮助你显示力扣周赛难度分数,让你更好地了解题目的难度,从而合理安排学习计划。算法学习路线推荐基础夯实:先过B站“灵茶山艾府”的“基础算法......
  • 力扣leetcode 416.分割等和子集 动态规划 0-1背包
    题目:给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。示例1:输入:nums=[1,5,11,5]输出:true解释:数组可以分割成[1,5,5]和[11]。示例2:输入:nums=[1,2,3,5]输出:false解释:数组不能分割成......
  • LeetCode热题100-两数相加【JavaScript讲解】
    题目:题解:根据题目(2->4->3)+(5->6->4)=(7->0->8),根据加法的计算过程我们知道首先从低位开始算起,也就是说应该先计算2+5=7;4+6=10,向前进一位,此处取余数0;3+4+进一位的1=8;所以答案是7->0->8。最关键的是最后的进位一定要记得,如果最后相加的和需要进位!!!解题代码:/***......
  • LeetCode100之分割回文串(131)--Java
    1.问题描述        给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串。返回 s 所有可能的分割方案。        示例1输入:s="aab"输出:[["a","a","b"],["aa","b"]]    示例2 输入:s="a"输出:[["a"]]        提......