有效的括号

题目来源于力扣:有效的括号

题目

题目
示例
提示
题目提供的函数接口如下

1
2
3
bool isValid(char* s) {

}

思路

阅读题目可以考虑到,所有的符号都是顺序压入先输入的右括号总是与后输入的左括号匹配,随着右括号的顺序输入,左括号呈现逆序依次弹出与右括号匹配

顺序压入逆序弹出,什么样的结构可以实现这个功能呢?答案是

栈的在之前的文章中讲解过:

随便例举一串有效括号”  {  [  (  )  (  )  ]  }  
很容易可以发现右括号需要匹配的是离自己最近的左括号

那么按照这个思路我们将s遍历遇到左括号就入栈遇到右括号与栈顶括号匹配,如果无效那么直接返回false,如果有效那么将栈顶括号弹出,继续遍历s中下一个括号。

直到s中所有括号遍历完,跳出这个循环

接下来思考一个问题,前面的程序是否有遗漏的情况?
当然有

因为s可以没有括号,可以只有左括号,可以只有右括号
因此还需要对特殊情况做处理

判断左右括号使用的是 if…else,实际上 if 后面的条件只判断了是否为左括号。
所以 s 中如果没有括号,或者只有右括号,都会直接执行else语句,将当前的右括号或者空字符与栈顶匹配,但是此时栈是空的,所以在获取栈顶之前需要对栈进行判空,如果栈为空那么直接返回false即可

如果只有左括号,程序将会一直入栈,然后循环结束。其实仔细思考,有效括号在匹配完之后,左右括号相互抵消,最终循环完毕栈为空。所以在循环结束之后立刻对栈判空,如果不为空,说明里面还有残留的左括号,那么返回false,如果为空,此时才真正说明字符串是有效的

所有的流程和思路就是这样,那么AC代码我就直接放在下面了

代码

写下面的代码之前,别忘了先将标准的栈操作 ctrl cctrl v到前面,供算法程序调用
程序员最快乐的应该就是 cv 吧😋(Doge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
bool isValid(char* s) {
ST st;
STInit(&st);
while(*s)
{
//左括号入栈
if(*s == '(' || *s == '[' || *s == '{')
{
STPush(&st,*s);
}
else//右括号匹配
{
//判空,防止s为空或者只有右括号
if(STEmpty(&st))
{
STDestroy(&st);
return false;
}
char top = STTop(&st);
STPop(&st);
if(top == '(' && *s != ')'
|| top == '[' && *s != ']'
|| top == '{' && *s != '}')
{
STDestroy(&st);
return false;
}
}
++s;
}
//栈不为空时说明有多余的右括号
bool ret = STEmpty(&st);
STDestroy(&st);
return ret;
}

下面是通过截图
通过

如果你有更高性能的实现方式,欢迎在评论区探讨

注意

最后最后最后,不论返回true还是false,不要忘记在返回前将栈进行销毁,虽然这只是一道题,但是要保持回收垃圾的习惯,否则真正在程序运行时,留下的垃圾很快就会导致内存耗尽并崩溃

如果文章内容有误,欢迎指出