leetcode 面试经典 150 题:有效的括号

链接有效的括号
题序号20
题型字符串
解法
难度简单
熟练度✅✅✅

题目

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

示例 1
输入:s = “()”
输出:true

示例 2
输入:s = “()[]{}”
输出:true

示例 3
输入:s = “(]”
输出:false

示例 4
输入:s = “([])”
输出:true

提示
1 <= s.length <= 104
s 仅由括号 ‘()[]{}’ 组成

题解

  1. 核心思想:判断括号是否有效,关键在于匹配。我们需要确保每个左括号都能找到对应的右括号,并且它们的顺序是正确的。为此,可以使用栈(Stack)来实现。
  2. 栈(stack)
    • 栈是一种后进先出(LIFO)的数据结构,适合处理括号匹配的问题。
    • 每当遇到左括号时,将其压入栈中。
    • 每当遇到右括号时,检查栈顶是否为匹配的左括号。
  3. 复杂度:时间复杂度为O(n),其中 n 是字符串 s 的长度。空间复杂度为O(n),由栈的大小决定,哈希表的空间是常数项,因为常数项在大O表示法中是可以忽略的。这意味着算法的空间需求主要取决于输入数据的大小,而与字符集的大小无关。
  4. c++ 实现算法
bool isValid(string s) {
    // 用栈保存未匹配的左括号
    stack<char> st;

    // 使用哈希表存储括号的映射关系
    //键(Key):右括号,包括 ')'、']' 和 '}'。
    //值(Value):对应的左括号,包括 '('、'[' 和 '{'。

    unordered_map<char, char> brackets = {
        {')', '('},
        {']', '['},
        {'}', '{'}
    };

    for (char c : s) {

        // 如果是右括号
        //在 unordered_map 中,count(key) 用于检查给定的 键key 是否存在于哈希表中
        //如果 key 存在,返回 1. 如果 键key 不存在,返回 0
        if (brackets.count(c)) {

            // 栈顶字符与右括号的匹配
            //检查栈是否为空,或者栈顶是否与当前右括号的匹配左括号相同
            //通过 brackets[c] 找到右括号对应的左括号,如果 c 是 ')',brackets[c] 就是 '('。
            if (!st.empty() && st.top() == brackets[c]) {

                st.pop(); // 匹配成功,移除栈顶
            } 
            else {
                return false; // 匹配失败
            }
        } 
        else {
            // 如果是左括号,入栈
            st.push(c);
        }
    }

    // 栈为空表示所有括号都匹配成功
    return st.empty();
}
  1. 算法推演:

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

  • 遍历字符 ‘{’:入栈 st = [‘{’]。
  • 遍历字符 ‘[’:入栈 st = [‘{’, ‘[’]。
  • 遍历字符 ‘(’:入栈 st = [‘{’, ‘[’, ‘(’]。
  • 遍历字符 ‘)’: 栈顶为 ‘(’,匹配成功,弹出栈顶 st = [‘{’, ‘[’]。
  • 遍历字符’]‘: 栈顶为 ‘[’,匹配成功,弹出栈顶 st = [’{']。
  • 遍历字符 ‘}’: 栈顶为 ‘{’,匹配成功,弹出栈顶 st = []。

遍历结束,栈为空,返回 true。

  1. c++ 完整demo
#include <iostream>
#include <stack>
#include <unordered_map>
#include <string>

using namespace std;

bool isValid(string s) {
    // 用栈保存未匹配的左括号
    stack<char> st;

    // 使用哈希表存储括号的映射关系
    //键(Key):右括号,包括 ')'、']' 和 '}'。
    //值(Value):对应的左括号,包括 '('、'[' 和 '{'。

    unordered_map<char, char> brackets = {
        {')', '('},
        {']', '['},
        {'}', '{'}
    };

    for (char c : s) {

        // 如果是右括号
        //在 unordered_map 中,count(key) 用于检查给定的 键key 是否存在于哈希表中
        //如果 key 存在,返回 1. 如果 键key 不存在,返回 0
        if (brackets.count(c)) {

            // 栈顶字符与右括号的匹配
            //检查栈是否为空,或者栈顶是否与当前右括号的匹配左括号相同
            //通过 brackets[c] 找到右括号对应的左括号,如果 c 是 ')',brackets[c] 就是 '('。
            if (!st.empty() && st.top() == brackets[c]) {

                st.pop(); // 匹配成功,移除栈顶
            } 
            else {
                return false; // 匹配失败
            }
        } 
        else {
            // 如果是左括号,入栈
            st.push(c);
        }
    }

    // 栈为空表示所有括号都匹配成功
    return st.empty();
}

int main() {
    string s = "{[()]}";
    if (isValid(s)) {
        cout << "true" << endl;
    } else {
        cout << "false" << endl;
    }
    return 0;
}

数据结构之 { 栈 }

  1. 数据结构中的栈(Stack)是一种遵循“后进先出”(Last In First Out,简称LIFO)原则的有序集合。这意味着最后添加到栈中的元素会首先被移除。栈通常用于处理递归调用、函数调用、表达式求值、括号匹配等场景。
  2. 栈的基本操作包括:
    • 压栈(Push):将一个元素添加到栈的顶部。
    • 弹栈(Pop):移除并返回栈顶部的元素。
    • 查看栈顶元素(Peek 或 Top):返回栈顶部的元素但不移除它。
    • 检查栈是否为空(IsEmpty):检查栈中是否有元素,如果有返回false,否则返回true。
    • 获取栈的大小(Size):返回栈中元素的数量。
  3. 栈可以用数组或链表来实现。数组实现的栈在空间上是连续的,而链表实现的栈在空间上可以是非连续的。
  4. 栈的应用场景:
    • 函数调用:在函数调用时,系统会将函数的参数、返回地址以及局部变量压入栈中,函数执行完毕后,这些信息会被弹栈。
    • 递归:递归函数的每次调用都会创建一个新的栈帧,用于存储局部变量和参数。
    • 括号匹配:检查代码中的括号是否正确匹配,可以使用栈来存储遇到的开括号,并在遇到闭括号时检查是否匹配。
    • 表达式求值:在计算表达式时,可以使用栈来存储操作数和操作符,以正确计算表达式的值。
    • 回溯算法:在搜索和图算法中,栈可以用来存储路径,以便在需要时回溯到上一个状态。
  5. 栈是一种非常基础且重要的数据结构,它在计算机科学和软件开发中有着广泛的应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959465.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

国产编辑器EverEdit - 输出窗口

1 输出窗口 1.1 应用场景 输出窗口可以显示用户执行某些操作的结果&#xff0c;主要包括&#xff1a; 查找类&#xff1a;查找全部&#xff0c;筛选等待操作&#xff0c;可以把查找结果打印到输出窗口中&#xff1b; 程序类&#xff1a;在执行外部程序时(如&#xff1a;命令窗…

小游戏源码开发搭建技术栈和服务器配置流程

近些年各种场景小游戏开发搭建版本层出不穷,山东布谷科技拥有多年海内外小游戏源码开发经验&#xff0c;现为从事小游戏源码开发或游戏运营的朋友们详细介绍小游戏开发及服务器配置流程。 一、可以对接到app的小游戏是如何开发的 1、小游戏源码开发的需求分析&#xff1a; 明…

Linux C\C++编程-文件位置指针与读写文件数据块

【图书推荐】《Linux C与C一线开发实践&#xff08;第2版&#xff09;》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践&#xff08;第2版&#xff09;&#xff08;Linux技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 Linu…

一文简单回顾复习Java基础概念

还是和往常一样&#xff0c;我以提问的方式回顾复习&#xff0c;今天回顾下Java小白入门应该知道的一些基础知识 Java语言有哪些特点呢&#xff1f; Java语言的特点有&#xff1a; 面向对象&#xff0c;主要是封装、继承、多态&#xff1b;平台无关性&#xff0c;“一次编写…

Redis实战(黑马点评)——关于缓存(缓存更新策略、缓存穿透、缓存雪崩、缓存击穿、Redis工具)

redis实现查询缓存的业务逻辑 service层实现 Overridepublic Result queryById(Long id) {String key CACHE_SHOP_KEY id;// 现查询redis内有没有数据String shopJson (String) redisTemplate.opsForValue().get(key);if(StrUtil.isNotBlank(shopJson)){ // 如果redis的数…

神经网络|(四)概率论基础知识-古典概型

【1】引言 前序学习了线性回归的基础知识&#xff0c;了解到最小二乘法可以做线性回归分析&#xff0c;但为何最小二乘法如此准确&#xff0c;这需要从概率论的角度给出依据。 因此从本文起&#xff0c;需要花一段时间来回顾概率论的基础知识。 【2】古典概型 古典概型是我…

【C++】特殊类设计、单例模式与类型转换

目录 一、设计一个类不能被拷贝 &#xff08;一&#xff09;C98 &#xff08;二&#xff09;C11 二、设计一个类只能在堆上创建对象 &#xff08;一&#xff09;将构造函数私有化&#xff0c;对外提供接口 &#xff08;二&#xff09;将析构函数私有化 三、设计一个类只…

微服务网关鉴权之sa-token

目录 前言 项目描述 使用技术 项目结构 要点 实现 前期准备 依赖准备 统一依赖版本 模块依赖 配置文件准备 登录准备 网关配置token解析拦截器 网关集成sa-token 配置sa-token接口鉴权 配置satoken权限、角色获取 通用模块配置用户拦截器 api模块配置feign…

16.好数python解法——2024年省赛蓝桥杯真题

问题描述 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位…)上的数字是奇数,偶数位(十位、千位、十万位…)上的数字是偶数,我们就称之为“好数”。 给定一个正整数N,请计算从1到N一共有多少个好数。 输入格式 一个整数N。 输出格式 一个整数代表答案。 样例输入 1 …

2025年数学建模美赛 A题分析(2)楼梯使用频率数学模型

2025年数学建模美赛 A题分析&#xff08;1&#xff09;Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析&#xff08;2&#xff09;楼梯磨损分析模型 2025年数学建模美赛 A题分析&#xff08;3&#xff09;楼梯使用方向偏好模型 2025年数学建模美赛 A题分…

Redis实战(黑马点评)——涉及session、redis存储验证码,双拦截器处理请求

项目整体介绍 数据库表介绍 基于session的短信验证码登录与注册 controller层 // 获取验证码PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {return userService.sendCode(phone, session);}// 获…

Brightness Controller-源码记录

Brightness Controller 亮度控制 一、概述二、ddcutil 与 xrandr1. ddcutil2. xrandr 三、部分代码解析1. icons2. ui3. utilinit.py 一、概述 项目&#xff1a;https://github.com/SunStorm2018/Brightness.git 原理&#xff1a;Brightness Controlle 是我在 Ubuntu 发现上调…

STM32简介

STM32简介 STM32是ST公司基于ARMCortex-M内核开发的32位微控制器 &#xff08;Microcontroller&#xff09; MCU微控制器、MPU微处理器、CPU中央处理器 1.应用领域 STM32常应用于嵌入式领域。 如智能车&#xff1a;循迹小车 读取光电传感器或者摄像头的数据&#xff0c;…

qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别

qt-C笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别 code review! 参考笔记 1.qt-C笔记之重写QGraphicsItem的paint方法(自定义QGraphicsItem) 文章目录 qt-C笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphic…

浏览器IndexedDB占用大

使用鲁大师清理后&#xff0c;用 SpaceSniffer 查看C盘占用情况&#xff0c;发现浏览器的 IndexedDB 有3个文件夹占用特别大&#xff0c;从文件名看是 youku&#xff0c;bilibili&#xff0c;v.qq.com&#xff0c;浏览器的数据库并不需要长期保存&#xff0c;删除这3个文件夹&a…

MongoDB部署模式

目录 单节点模式&#xff08;Standalone&#xff09; 副本集模式&#xff08;Replica Set&#xff09; 分片集群模式&#xff08;Sharded Cluster&#xff09; MongoDB有多种部署模式&#xff0c;可以根据业务需求选择适合的架构和部署方式。 单节点模式&#xff08;Standa…

将 OneLake 数据索引到 Elasticsearch - 第二部分

作者&#xff1a;来自 Elastic Gustavo Llermaly 及 Jeffrey Rengifo 本文分为两部分&#xff0c;第二部分介绍如何使用自定义连接器将 OneLake 数据索引并搜索到 Elastic 中。 在本文中&#xff0c;我们将利用第 1 部分中学到的知识来创建 OneLake 自定义 Elasticsearch 连接器…

Formality:时序变换(三)(相位反转)

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 一、引言 时序变换在Design Compiler的首次综合和增量综合中都可能发生&#xff0c;它们包括&#xff1a;时钟门控(Clock Gating)、寄存器合并(Register Merging)、…

php代码审计2 piwigo CMS in_array()函数漏洞

php代码审计2 piwigo CMS in_array()函数漏洞 一、目的 本次学习目的是了解in_array()函数和对项目piwigo中关于in_array()函数存在漏洞的一个审计并利用漏洞获得管理员帐号。 二、in_array函数学习 in_array() 函数搜索数组中是否存在指定的值。 in_array($search,$array…

房租管理系统的智能化应用助推租赁行业高效运营与决策优化

内容概要 在现代租赁行业中&#xff0c;房租管理系统的智能化应用正在逐步成为一个不可或缺的工具。通过整合最新技术&#xff0c;这些系统为租赁管理的各个方面提供了极大的便利和效率提升。从房源管理到合同签署再到财务监控&#xff0c;智能化功能能够帮助运营者在繁琐的事…