备战秋招60天算法挑战,Day13

题目链接: https://leetcode.cn/problems/valid-parentheses/

视频题解: https://www.bilibili.com/video/BV1hT421Q7g3/

LeetCode20.有效的括号

在我们刷题的时候,适当的借助现有的数据结构往往会起到事半功倍的效果,今天我们讨论一下栈的使用。栈的特点是先进后出,利用栈的这个特点可以巧妙的解决很多问题,借助下面这道题我们进一步来体会一下栈的妙用。

题目描述

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

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

举个例子:

复制代码
输入:s = "()"
输出:true

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

视频题解

有效的括号

思路来源

思路来源

思路解析

首先要理解题意,什么才是题目中描述的有效括号,比如s = "({)[]}", 如下图,把同类型的括号单独按顺序拆出来,每种类型的括号都是能闭合的,但是s并不是合法的。

因为最先和'{'闭合的是')',违背了 左括号必须用相同类型的右括号闭合 这个原则。而且上面的这种拆法本身也违反了 左括号必须以正确的顺序闭合的原则

很多同学都因为没有理解透题意面试的时候没有把这道题正确的做出来,非常可惜。

理清题意,只需要借助栈,遍历字符串当元素为'(''{''['就压栈,遇到')''}'']'就和栈顶元素比较,能组成合法括号就弹出栈顶元素,不能组成合法括号就返回false,直到遍历完字符串,栈为空就返回true。整个匹配过程就像我们平时玩的小游戏消消乐。

举个简单的例子,s = "({}[])",匹配过程如下图:

遍历完s以后,栈是空的,这就说明字符串s是合法的。

C++代码

cpp 复制代码
class Solution {
public:
    //判断两个字符能否组成合法的括号
    bool isMatch(char& left, char& right) {
        if (left == '(' && right == ')') {
            return true;
        } else if (left == '{' && right == '}') {
            return true;
        } else if (left == '[' && right == ']') {
            return true;
        } else {
            return false;
        }
    }
    bool isValid(string s) {
        stack<char> st_ch;
        int s_len = s.length();
        //s的长度为奇数,一定是非法的
        if (s_len % 2 != 0) {
            return false;
        } 
        for (auto& ch:s) {
            //遇到'('、'{'、'['就压栈
            if (ch == '(' || ch == '{' || ch == '[')
                st_ch.push(ch);
            //遇到')'、'}'、']'就和栈顶元素比较,能组成合法括号就弹出栈顶元素
            //栈的操作一定要小心,不要对空栈进行pop操作
            else if (!st_ch.empty() && isMatch(st_ch.top(), ch))
                st_ch.pop();
            else 
                return false;
        }
        if (st_ch.empty()) {
            return true;
        } 
        return false;
    }
};

java代码

java 复制代码
class Solution {
    //判断两个字符能否组成合法的括号
    private boolean isMatch(char left, char right) {
        if (left == '(' && right == ')') {
            return true;
        } else if (left == '{' && right == '}') {
            return true;
        } else if (left == '[' && right == ']') {
            return true;
        } else {
            return false;
        }
    }
    
    public boolean isValid(String s) {
        Stack<Character> st_ch = new Stack<>();
        int s_len = s.length();
        //s的长度为奇数,一定是非法的
        if (s_len % 2 != 0) {
            return false;
        } 
        for (char ch : s.toCharArray()) {
            //遇到'('、'{'、'['就压栈
            if (ch == '(' || ch == '{' || ch == '[')
                st_ch.push(ch);
            //遇到')'、'}'、']'就和栈顶元素比较,能组成合法括号就弹出栈顶元素
            //栈的操作一定要小心,不要对空栈进行pop操作
            else if (!st_ch.empty() && isMatch(st_ch.peek(), ch))
                st_ch.pop();
            else 
                return false;
        }
        return st_ch.empty();
    }
}

python代码

python 复制代码
class Solution:
    def isValid(self, s: str) -> bool:
        st_ch = []
        s_len = len(s)
        #s的长度为奇数,一定是非法的
        if s_len % 2 != 0:
            return False
        for ch in s:
            #遇到'('、'{'、'['就压栈
            if ch == '(' or ch == '{' or ch == '[':
                st_ch.append(ch)
            #遇到')'、'}'、']'就和栈顶元素比较,能组成合法括号就弹出栈顶元素
            #栈的操作一定要小心,不要对空栈进行pop操作
            elif st_ch and self.isMatch(st_ch[-1], ch):
                st_ch.pop()
            else:
                return False
        return not st_ch
    
    #判断两个字符能否组成合法的括号
    def isMatch(self, left, right):
        if left == '(' and right == ')':
            return True
        elif left == '{' and right == '}':
            return True
        elif left == '[' and right == ']':
            return True
        else:
            return False

复杂度分析

时间复杂度: 只遍历一遍字符串,故时间复杂度是O(n)n为字符串长度。

空间复杂度: 我们用到了一个栈st_ch,故空间复杂度为O(n)n最大为字符串长度。

相关推荐
Gigavision13 分钟前
基于BUAA-MIHR数据集的噪声解耦对比学习算法
人工智能·python·深度学习·算法
鹿角片ljp24 分钟前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
IPdodo_26 分钟前
跨境 API 调用不稳定怎么办:出口、超时重试与链路监控的实践
网络·python·网络协议
Madison-No71 小时前
搭建项目测试环境
linux·运维·服务器·python
计算机编程-吉哥1 小时前
YOLO26 vs YOLO11 vs YOLOv8:深度学习咖啡果实成熟度分割系统【计算机毕业设计选题推荐】
人工智能·python·深度学习·yolo·django·毕业设计
彧azz2 小时前
算法设计与分析:贪心与动态规划
数据结构·学习·算法·贪心算法·动态规划
泡海椒2 小时前
PDF 表格样式优化:jquick-pdf 边框、圆角、背景色
java·开发语言·pdf
大衛說2 小时前
11 · 异常处理与日志
python
auto_go2 小时前
Python 实战指南(7)——账本动不动就崩?先把“魔法字符串”和“裸报错”干掉
python