题目来源于力扣:有效的括号
题目
题目提供的函数接口如下
bool isValid(char* s) {
}
思路
阅读题目可以考虑到,所有的符号都是顺序压入,先输入的右括号总是与后输入的左括号匹配,随着右括号的顺序输入,左括号呈现逆序依次弹出与右括号匹配
顺序压入逆序弹出,什么样的结构可以实现这个功能呢?答案是栈
栈的在之前的文章中讲解过:数据结构——栈
随便例举一串有效括号" { [ ( ) ( ) ] } "
很容易可以发现右括号需要匹配的是离自己最近的左括号
那么按照这个思路我们将s遍历,遇到左括号就入栈,遇到右括号与栈顶括号匹配,如果无效那么直接返回false,如果有效那么将栈顶括号弹出,继续遍历s中下一个括号。
直到s中所有括号遍历完,跳出这个循环
接下来思考一个问题,前面的程序是否有遗漏的情况?
当然有
因为s可以没有括号,可以只有左括号,可以只有右括号
因此还需要对特殊情况做处理
判断左右括号使用的是 if…else,实际上 if 后面的条件只判断了是否为左括号。
所以 s 中如果没有括号,或者只有右括号,都会直接执行else语句,将当前的右括号或者空字符与栈顶匹配,但是此时栈是空的,所以在获取栈顶之前需要对栈进行判空,如果栈为空那么直接返回false即可
如果只有左括号,程序将会一直入栈,然后循环结束。其实仔细思考,有效括号在匹配完之后,左右括号相互抵消,最终循环完毕栈为空。所以在循环结束之后立刻对栈判空,如果不为空,说明里面还有残留的左括号,那么返回false,如果为空,此时才真正说明字符串是有效的
所有的流程和思路就是这样,那么AC代码我就直接放在下面了
代码
写下面的代码之前,别忘了先将标准的栈操作 ctrl c ,ctrl v到前面,供算法程序调用
程序员最快乐的应该就是 cv 吧(Doge
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;
}
下面是AC截图
注意
最后最后最后,不论返回true还是false,不要忘记在返回前将栈进行销毁,虽然这只是一道题,但是要有回收垃圾的习惯,否则真正写程序时,留下的垃圾很快就会导致内存耗尽并崩溃