目录
1:题目分析
1):本题给定了我们一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
2):下面是3个示例,如果两相邻的左右括号是同一种字符(同一种括号),那么我么就直接返回true,反之,如果不相等就返回false
2:解题思路
1):这里的解题思路就是当s中从左到右依次开始,如果第一个是左括号( '(' '[' '{'),那么我们就让括号入栈(进栈),然后在看下一个括号,那么这里就会有两种情况分别是下图中举例的的两种情况,如果是情况1:那么我们还需要让左括号继续入栈知道遇到右括号位置,如果是情况2:在第二个位置就碰到了右括号,那么我们就需要让刚刚入栈的左括号出栈顶,和右括号进行匹配
情况1:需要先让左括号入栈5次直到遇见第一个右括号'}'为止
情况2:我们需要在边入栈的同时还要让左括号出栈来同右括号匹配
3:代码实现和解析
1):这里我们是在力扣中用C语言去实现的,而C语言中没有自己的栈区,所以在开头我们需要自己手搓栈以及栈的初始化、销毁、删除、插入.......等,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
typedef int SLDatatype;
typedef struct Stack
{
SLDatatype* a;
int top;
int capacity;
}ST;
//初始化和销毁
void STInit(ST* pst);
void STDestory(ST* pst);
//入栈 出栈
void STPush(ST* pst, SLDatatype x);
void STPop(ST* pst);
//取栈顶数据
SLDatatype STTop(ST* pst);
//判空
bool STEmpty(ST* pst);
//获取数据个数
int STSize(ST* pst);
//初始化
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->top = pst->capacity = 0;
//pst->top = pst->capacity = -1;
}
//销毁
void STDestory(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
//top指针指向栈顶的下一个位置
pst->top = 0;
//top指针指向栈顶数据
//pst->top = -1;
pst->capacity = 0;
}
//入栈
void STPush(ST* pst, SLDatatype x)
{
assert(pst);
//扩容
if (pst->top == pst->capacity)
{
int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
SLDatatype* tmp = (SLDatatype*)realloc(pst->a, newCapacity * sizeof(SLDatatype));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
pst->a = tmp;
pst->capacity = newCapacity;
}
pst->a[pst->top] = x;
pst->top++;
}
//出栈
void STPop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
pst->top--;
}
//取栈顶数据
SLDatatype STTop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
return pst->a[pst->top - 1];
}
//判空
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
//获取数据个数
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
2):首先我们先用初始化一下栈,然后开我们的第一步,用if语句让字符串中的左括号入栈,如果*s == '(' || *s == '[' || *s == '{' ,那么我们就插入到我们的栈当中去,这一步也就是入栈
//是左括号就入栈
if(*s == '(' || *s == '[' || *s == '{')
{
STPush(&st,*s);
}
3):一:接下来我们用一个else语句来处理另外的情况,我们这里先用一个整形(int)的top来接收入栈后栈顶的左括号,也就是取栈顶的数据,然后这里需要删除一下栈顶的数据,为了方便下一次我们取出另外一个左括号
//取栈顶的数据
char top = STTop(&st);
STPop(&st);
二:在这之前我们需要判空一下,如果为NULL就直接返回,这里是为了防止字符串s中只有一个左括号出现
if(STEmpty(&st))
{
return false;
}
4):这里我们用if语句来处理不匹配的情况,有的人会问这里我们为什么不处理他们匹配的情况呢?这里我们如果处理他们相同的的话并不能得到什么结果(结论),并且还要处理不同的括号类型,所以这里我直接处理他们不匹配的的情况,处理好以后就可以直接return false了,每处理一次*s我们就++s一下
//不匹配
if((top == '(' && *s != ')')
|| (top == '[' && *s != ']')
||(top == '{' && *s != '}'))
{
STDestory(&st);
return false;
}
5):最后这里我们还要注意一下当栈不为空时,说明左括号比右括号多,左右括号的数量不匹配,如果数量不匹配,这里可以用一个bool来判断,为真就返回false,为假就返回true
//栈不为空,说明左括号比右括号多,数量不匹配
bool ret = STEmpty(&st);
STDestory(&st);
4:总代码
bool isValid(char* s) {
ST st;
STInit(&st);
while(*s)
{
//是左括号就入栈
if(*s == '(' || *s == '[' || *s == '{')
{
STPush(&st,*s);
}
else//是右括号就取栈栈顶的数(左括号)尝试比较
{
if(STEmpty(&st))
{
return false;
}
//取栈顶的数据
char top = STTop(&st);
STPop(&st);
//不匹配
if((top == '(' && *s != ')')
|| (top == '[' && *s != ']')
||(top == '{' && *s != '}'))
{
STDestory(&st);
return false;
}
}
++s;
}
//栈不为空,说明左括号比右括号多,数量不匹配
bool ret = STEmpty(&st);
STDestory(&st);
return ret;
}
以上就是有效括号问题的所有思路和分析了,创作不易,求求大家点个小赞赞,感谢各位老们的赏脸观看,随手点个赞,养成好习惯,如有问题,感谢反馈!