(LeetCode)有效的括号【栈】

目录

1.题目要求

2.题目理解以及思路分析 

3.代码分部讲解

(1)第一部分

(2)第二部分

(3)第三部分

4.总结


题目要求

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

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

 

示例 1:

输入:s = "( )"
输出:true


示例 2:

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


示例 3:

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


示例 4:

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


示例 5:

输入:s = "{ [ ] }"
输出:true
 

提示:

1 <= s.length <= 104
s 仅由括号 '()[]{}' 组成

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-parentheses

 

这道题目用 “栈” 的方法和思想会更容易理解同时可以更简单的解决这个问题。

题目理解以及思路分析 

(一) 这个题目就是将括号进行配对,因此便有配对成功与失败两种情况。

(二) 根据题意可以看出 括号的长度必须为 偶数 ,否则一定是配对失败。

(三) 右括号前必须有相对应的左括号,这样才可能配对成功;如果右括号前面没有相对应的左括号则其一定配对不成功。

(四) 为了使得配对的思路清晰同时保证不乱,我们采用“栈”的方法,即将其对应的左括号当作“栈顶”,与后面的右括号进行判断,如果左右括号对应则二者抵消,否则判定错误。

为了更好便于大家理解,我做了上面的思路图解,通过图片我们可以明白 “栈” 的思想对于这道题目的使用。希望大家可以好好的消化理解。(图片有些模糊)

代码分部讲解

通过上面的思路分析以及对题目的理解,下面我们将进行代码的实现

第一部分

//定义一个函数,对左右括号进行一个判断
char Pan(char a)
  {
    //如果是右括号,则我们返回其对应的左括号
    if(a == ')')
      return '(';
    if(a == ']')
      return '[';
    if(a == '}')
      return '{';
    //如果是左括号,我们返回 0 
    else
      return 0;
  }

这一部分的目的其实是为下面的判断做铺垫。

第二部分

bool isValid(char * s){
    int top = 0,n,i,b;
    char ch;
    n = strlen(s);  //求出字符串的长度
    int count[n];   //定义一个数组————栈
    if(n % 2 == 1)  //首先进行判断,如果字符串的长度为 奇数,则无论如何都无法配对成功
      return false;
    for(i = 0;i < n;i ++)
      {
        ch = Pan(s[i]);
        if(ch)
          {
            if(top == 0||count[top - 1] != ch)
              return false;
            top--;
          }
        else
          {
            b = top++;
            count[b] = s[i];
          }
      }
    return top == 0;
}

对于这部分的代码,简单的部分我已经将解释放在了里面,下面我们将抽出来重点的部分着重讲解:

 这一部分特别重要,同时也不好理解!!!希望大家认真看完

    for(i = 0;i < n;i ++)
      {
        ch = Pan(s[i]);
        if(ch)
          {
            if(top == 0||count[top - 1] != ch)
              return false;
            top--;
          }
        else
          {
            b = top++;
            count[b] = s[i];
          }
      }

首先进行 for 循环,这个很容易理解,因为我们要进行遍历,然后才能进行配对。

调用 Pan 函数 ,这个时候前面我们定义的函数的作用就出来了,我们接着往下看。

调用函数后,我们就开始判断了,看看是左括号还是右括号,通过上面我们定义的函数可以知道如果此时 s[ i ] 右括号,则返回的函数值为其对应的 左括号;如果此时 s[ i ]左括号,则返回的函数值为 0

        if(ch)
          {
            if(top == 0||count[top - 1] != ch)
              return false;
            top--;
          }

执行这一步说明此时 Pan 函数返回的其对应的 左括号,也就是说其原数据为 右括号,根据上面的解释图解我们可以得知,如果是 右括号 我们必须进行配对,因此:

if(top == 0||count[top - 1] != ch)
   return false;
top--;

这一步便是配对的过程,如果 top 为 0(即栈为空),或者栈的上一个栈顶不等于此时Pan函数的返回值,则说明配对失败。

如果配对成功,则 top--,即弹出栈内(抵消)。

这个时候很多读者不理解最后一个

count[top - 1] != ch

首先我们知道如果原字符串里是右括号 则 Pan 函数返回的是其对应的左括号,因此如果栈(count)上一个栈顶与其不相等就意味着二者不能配对成功。(希望大家好好理解这一点)

 讲完了一种情况,接下来还剩下一种情况:Pan 函数返回值为 0 的情况。

        else
          {
            b = top++;
            count[b] = s[i];
          }
      }

明白了上面的讲解,那这一部分就显得很好理解了,原字符串如果是 右括号 我们便进行判断,如果是 左括号,我们就直接 压入栈内,等待与其配对的括号出现。

 第三部分

附上完整的代码

char Pan(char a)
  {
    if(a == ')')
      return '(';
    if(a == ']')
      return '[';
    if(a == '}')
      return '{';
    else
      return 0;
  }

bool isValid(char * s){
    int top = 0,n,i,b;
    char ch;
    n = strlen(s);
    int count[n];
    if(n % 2 == 1)
      return false;
    for(i = 0;i < n;i ++)
      {
        ch = Pan(s[i]);
        if(ch)
          {
            if(top == 0||count[top - 1] != ch)
              return false;
            top--;
          }
        else
          {
            b = top++;
            count[b] = s[i];
          }
      }
    return top == 0;
}

总结

本题主要是用“栈”的思想来解决,用的十分巧妙的地方是,左右两括号配对成功后便弹出栈内,也就是抵消,这样减少了数据处理的困难程度。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简十三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值