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

相关推荐
Pniubi8 小时前
力扣73 矩阵置零
算法·leetcode·矩阵
天天被压力8 小时前
【A股分钟级高频数据完全手册 #11】券商实时行情数据接口:实时交易(券商源)接入与字段
java·人工智能·python
总裁余(余登武)8 小时前
【python项目】:1操作EXCEl自动化开发
python·自动化·excel
芝梵家电数据笔记8 小时前
用字段表核对暖菜板长期使用条件:结构、暖区、质保边界
python·家电·数据校验·dataclass·选购
天天被压力8 小时前
【A股分钟级高频数据完全手册 #12】股票五档盘口数据接口:买卖五档实时盘口解析
java·人工智能·python
Wang's Blog17 小时前
Java 项目实战: 交友项目 - FastDFS:入门案例
java·开发语言·交友
apcipot_rain18 小时前
C++转Java日记(03)
java·开发语言·c++
皮皮林55118 小时前
Java实现微信扫码登录
java
布莱克60518 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
xys_67818 小时前
深挖C++:类和对象(中)
开发语言·c++