栈--有效的括号(2)

本文介绍了栈在处理后缀表达式验证中的重要性,强调了栈的线性结构和一端操作特性,并通过实例展示了如何使用栈解决括号匹配问题。作者鼓励初学者亲手实现,以深化对栈的理解。
摘要由CSDN通过智能技术生成

前言:本文章才开始利用栈来解决该问题,但本人认为上一节的思路更加重要,且本文章延续上一篇文章思路,所以看这篇之前最好至少大致了解一下上一节思路。

关键知识点:栈。后面说一个本人对于栈的理解,栈的本质是线性结构+仅一端操作。我希望初学者不要和我当时一样只记得”先进后出",这个是运作特性,是由前面所说的本质导致的,只记住这个是很难理解栈以至于能手写出来栈代码的。

附加:(方便理解,可直接跳过)作者刚开始学习栈的时候十分迷惑,只能在一端进行操作,感觉十分麻烦,使用起来不如数组灵活,后面的学习逐渐意识到,它的”不便利性“正是它的优势,它所能进行的操作越有限,它考虑起来越简单。举一个类似理解:bool值相对于int值,正因为它只有两个值,我们使用起来才更加直观,遇到bool值我们会直接知道这多半是用来判断。(当然存储大小也是一小点)正如一般用栈,我们就知道它多半只会在一端进行操作。总言之,就是解决同一个问题,模型越简单越好,栈的操作有限性照成了它的简单性带来了便利。

  如上篇文章结束所言,我们仅对线性结构(字符串)一端进行操作,这符合栈的特性(线性结构+仅一端操作)。上篇文章中仅在一端操作的线性结构是等级数组level[10000],故我们可以转换为栈,当需要进元素时(遇到左括号)利用栈的push();当需要弹出元素与所遇到符号对比时(遇到右括号)利用栈的pop()。
  希望你看到这可以自己写出后面代码。

#include<stack>
class Solution {
public:
    bool isValid(string s) {
        int small, medium, large;
        small = medium = large = 0;
        stack<int> level;//int level[10000] = {0}; 
        int levelFlag = 0;
        for (int i = 0; i < s.length(); i++){
            if(s[i] == '('){
                small += 1;//handle require 1

                level.push(1);//也可以改成"(",直接用符号进行对比
                //levelFlag+=1;
                //level[levelFlag] = 1;
            }
            else if(s[i] == ')'){
                small -= 1; //handle require 1
                if(small < 0)
                    return false;
                
                int levelTop = -1;
                if (!level.empty())
                    levelTop = level.top();
                level.pop();
                if(levelTop != 1)
                    return false;
                /*
                if(level[levelFlag] == 1){//handle require 2
                    levelFlag--;
                }else
                    return false; //no match
                */
                
            }
            else if(s[i] == '['){
                medium += 1;

                level.push(2);
                //levelFlag+=1;
                //level[levelFlag] = 2;
            }
            else if(s[i] == ']'){
                medium -= 1;
                if(medium < 0)
                    return false;
                
                int levelTop = -1;
                if (!level.empty())
                    levelTop = level.top();
                level.pop();
                if(levelTop != 2 )
                    return false;
                /*
                if(level[levelFlag] == 2)
                    levelFlag--;
                else
                    return false; 
                */
            }
            else if(s[i] == '{')
            {
                large += 1;

                level.push(3);
                //levelFlag+=1;
                //level[levelFlag] = 3;
            }      
            else{
                large -= 1;
                int levelTop = -1;
                if (!level.empty())
                    levelTop = level.top();
                level.pop();
                if(levelTop != 3)
                    return false;
                /*
                if(large < 0)
                    return false;
                if(level[levelFlag] == 3)
                    levelFlag--;
                else
                    return false; 
                */
            }
        }
        if(large > 0 || medium > 0 || small > 0 )
            return false;
        return true;
    }
};

  很明显,这个代码十分的丑陋,并且还调用了库函数,应该比网上任何代码都要差劲,但它运行效率并不会低于其他代码,是一个“正确”的答案。希望读者能够理解为什么这里需要用到栈,为什么是对符号进行建立栈,以及在写后缀表达式这类题目时能够理解为什么要对符号建栈,为什么进去时需要等级对比。

  总结:如果有不了解库函数的同学,可以自行搜索一下,最好是自己手写出来,这并不困难。希望特别是初学者一定要自己写出来,即使是写了一天,也比抄别人代码,仅从表面上理解要好,写完了再去与网上更优秀的代码对比。

  文章不足之处,不方便理解处待指正。

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

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值