有效括号详解

目录

1:题目分析

2:解题思路

3:代码实现和解析

4:总代码


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;
}

以上就是有效括号问题的所有思路和分析了,创作不易,求求大家点个小赞赞,感谢各位老们的赏脸观看,随手点个赞,养成好习惯,如有问题,感谢反馈!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值