代码随想录53——栈与队列4——有效的括号

🌈hello,你好鸭,我是Ethan,西安电子科技大学大三在读,很高兴你能来阅读。

✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。
🏃人生之义,在于追求,不在成败,勤通大道。加油呀!

🔥个人主页:Ethan Yankang
🔥推荐:史上最强八股文 || 一分钟看完我的上千篇博客

🔥温馨提示:划到文末发现专栏彩蛋   点击这里直接传送

🔥本篇概览:数据结构与算法 || 详细讲解了用栈与队列来匹配有效的括号。🌈⭕🔥


【计算机领域一切迷惑的源头都是基本概念的模糊,算法除外】


🌈序言

算法乃我长久之志也,此关必过。今日得此代码随想录之良品辅助,应按此路学之习之,而长久不可懈怠。

前一系列文章详细讲解了栈与队列的互相表示,对基础要求较为严格,面试中遇到很考验人。建议先将这部分知识掌握之后再来学习本篇内容,点击查看。


🔥 代码随想录52——栈与队列3——用队列实现栈-CSDN博客

🔥 代码随想录系列所有算法精讲一键查阅


🌈引出

数据结构与算法应用往往隐藏在我们看不到的地方


题目:20. 有效的括号

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

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

示例 1:

  • 输入: "()"
  • 输出: true

示例 2:

  • 输入: "()[]{}"
  • 输出: true

示例 3:

  • 输入: "(]"
  • 输出: false

示例 4:

  • 输入: "([)]"
  • 输出: false

示例 5:

  • 输入: "{[]}"
  • 输出: true


剖析题干重点:

括号匹配问题,是一类典型题目,显然是栈来解决。不过使用双指针可能更加简便(后面发现用双指针还真解决不了。例如下面的情况,所以对称问题,这是栈的天地。)。


🔥思路分析:

题外话

括号匹配是使用栈解决的经典问题。

题意其实就像我们在写代码的过程中,要求括号的顺序是一样的,有左括号,相应的位置必须要有右括号。

如果还记得编译原理的话,编译器在 词法分析的过程中处理括号、花括号等这个符号的逻辑,也是使用了栈这种数据结构。

再举个例子,linux系统中,cd这个进入目录的命令我们应该再熟悉不过了。


cd a/b/c/../../

【相消了】


这个命令最后进入a目录,系统是如何知道进入了a目录呢 ,这就是栈的应用(其实可以出一道相应的面试题了)

所以栈在计算机领域中应用是非常广泛的。

有的同学经常会想学的这些数据结构有什么用,也开发不了什么软件,大多数同学说的软件应该都是可视化的软件例如APP、网站之类的,那都是非常上层的应用了,底层很多功能的实现都是基础的数据结构和算法。

所以数据结构与算法的应用往往隐藏在我们看不到的地方!

这里我就不过多展开了,先来看题。


进入正题

由于栈结构的特殊性,非常适合做对称匹配类的题目。

首先要弄清楚,字符串里的括号不匹配有几种情况。

一些同学,在面试中看到这种题目上来就开始写代码,然后就越写越乱。

建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。

先来分析一下 这里有三种不匹配的情况,

  1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 

    括号匹配1

  2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。 

    括号匹配2

  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配。 

    括号匹配3

我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。

动画如下:

20.有效括号


第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false;


那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了

分析完之后,代码其实就比较好写了,

但还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!


🌈最终代码:

class Solution {
    public boolean isValid(String s) {
        Deque<Character> deque = new LinkedList<>();
        char ch;
        for (int i = 0; i < s.length(); i++) {
            ch = s.charAt(i);
            //碰到左括号,就把相应的右括号入栈
            if (ch == '(') {
                deque.push(')');
            }else if (ch == '{') {
                deque.push('}');
            }else if (ch == '[') {
                deque.push(']');
            } else if (deque.isEmpty() || deque.peek() != ch) {
                return false; 
             // deque.isEmpty() 第三种情况:遍历字符串匹配的过程中,
             //栈已经为空了,没有匹配的字符了,
             //说明右括号没有找到对应的左括号 return false
             // deque.peek() != ch 第二种情况:遍历字符串匹配的过程中,
             //发现栈里没有我们要匹配的字符。所以return false
            }else {
                deque.pop();//匹配就消除一个右括号。
            }
        }
       
       //最后判断栈中元素是否匹配。如果剩余了就不等,说明有多的左括号没有匹配。消除完了就相等
        return deque.isEmpty();
    }
}

今日问题:


🔥今日总结:

1. 对称性问题是栈来解决的拿手好戏。


2. 技巧1

压入栈的不是左括号,而是与之匹配的右括号,之后再消除掉右括号。这样巧妙的将括号的匹配转化为相等问题了。


3.技巧2

使用左括号入栈是最好的解决方式,如果是左括号的话,还需要从栈底相匹配。而右括号直接用栈顶。天然的便捷。


右入栈        (总之记住右入栈最好!)

     直接可以使用与栈顶元素是否相等来判断

》】]] 】》


左入栈     

   这还真不能用相等==来做判断,还需要使用三重if来判断,很麻烦!deque.peek()=='['&&s[i]==']'  类似这样的循环共做3次,一看就恶心。

《【 [ ]】》



📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤收藏✅ 评论💬,大佬三连必回哦!thanks!!!
📚愿大家都能学有所得,功不唐捐!

👇下面是专栏彩蛋系列,你会喜欢的!(为了避免影响算法的简洁与优美,这里直接将之前的几十个专栏简化为3个部分,不过你点击开后发现惊喜。)👇


💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖

热门专栏

🌈🌈专栏彩蛋系列

🌈🌈史上最全八股文,欢迎收藏

🌈🌈一篇文章了解我的上千篇博客

💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖


  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值