备战秋招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最大为字符串长度。

相关推荐
SimonKing5 分钟前
OpenCode 在 IDEA 中使用 ACP 协议 VS 直接使用 TUI,哪个编程方式更是你的菜?
java·后端·程序员
tankeven8 分钟前
动态规划专题(11):区间动态规划之三角剖分问题
c++·算法·动态规划
黄粱梦醒11 分钟前
UV快速搭建新项目
python
NE_STOP13 分钟前
Redis--持久化之AOF
java
budingxiaomoli14 分钟前
注册中心的其他实现-Nacos
java·spring cloud·微服务
小学生-山海17 分钟前
【YOLO系列】基于YOLOv8/v11/v26与tkinter的车流量统计系统设计
python·yolo
joshchen21519 分钟前
强化学习基础(赵世钰)第一章
人工智能·深度学习·算法·机器学习·强化学习
Wyc7240920 分钟前
数据结构1
数据结构
zhangrelay20 分钟前
三分钟云课实践速通--C/C++程序设计--
linux·c语言·c++·笔记·学习·ubuntu
大大大大晴天️25 分钟前
Flink技术实践-Flink重启策略选型指南
java·大数据·flink