【LeetCode】括号匹配问题(C语言)| 动图演示,超详细哦~

文章目录

    • (1)题目描述
    • (2)解题思路

(1)题目描述

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

有效字符串需满足:

1、左括号必须用相同类型的右括号闭合。

2、左括号必须以正确的顺序闭合。

示例1:

输入:s = “( )”

输出:true

示例2:

输入:s = “( ) [ ] { }”

输出:true

示例3:

输入:s = “( ]”

输出:false

示例4:

输入:s = “( [ ) ]”

输出:false

示例5:

输入:s = “{ [ ] }”

输出:true


(2)解题思路

  • 利用栈的性质解决此题

  • 首先实现一个栈

  • 然后遍历字符串,如果遇到左括号( '(''{''[' ),将其压入栈中,如果遇到右括号( ')''}'']' ),将当前栈顶的左括号出栈,与其匹配,看是否是一对,若匹配失败,则返回false,匹配成功,则继续遍历字符串后面的字符。

  • 两种特殊情况:

  • (1)字符串中全是左括号,全部入栈了,遍历结束后,需要对栈判空一下,若不为空,返回false

  • (2)字符串中全是右括号,没有左括号则栈为空,所以在遍历字符串遇到右括号时需要判断一下当前栈是否为空,若为空,返回false

  • 图解算法(示例2)

【LeetCode】括号匹配问题(C语言)| 动图演示,超详细哦~_第1张图片
  • 图解算法(示例5)
【LeetCode】括号匹配问题(C语言)| 动图演示,超详细哦~_第2张图片
  • 代码如下

首先实现一个栈:

//定义可以动态增长的栈
typedef struct Stack
{
    char* a;
    int top;
    int capacity;
}Stack;
//初始化栈
void StackInit(Stack *ps)
{
    assert(ps);
    ps->a = NULL;
    ps->top = -1;
    ps->capacity = 0;
}
//销毁栈
void StackDestroy(Stack *ps)
{
    assert(ps);
    if(ps->a)
    {
        free(ps->a);
    }
    ps->a = NULL;
    ps->top = -1;
    ps->capacity = 0;
}
//入栈
void StackPush(Stack *ps, char x)
{
    assert(ps);
    if(ps->top == ps->capacity - 1)  //检查栈的容量是否已满
    {
        //扩容
        int newcapacity = (ps->capacity == 0) ? 4 : 2 * (ps->capacity);
        char* temp = realloc(ps->a, newcapacity * sizeof(char));
        if(temp == NULL)
        {
            perror("realloc");
            exit(-1);
        }
        ps->a = temp;
        ps->capacity = newcapacity;  //更新容量
    }
    ps->top++;
    ps->a[ps->top] = x;
}
//出栈
void StackPop(Stack *ps)
{
    assert(ps);
    assert(ps->top != -1);  //栈不能为空
    ps->top--;
}
//获取栈顶元素
char StackTop(Stack *ps)
{
    assert(ps);
    return ps->a[ps->top];
}
//检查栈是否为空
bool StackEmpty(Stack *ps)
{
    assert(ps);
    return ps->top == -1;
}

核心代码:

bool isValid(char *s){
    Stack s1;
    StackInit(&s1);
    while(*s)
    {
        if(*s == '(' || *s == '[' || *s == '{')  //当前字符为左括号
        {
            StackPush(&s1, *s);  //入栈
        }
        else  //当前字符为右括号
        {
            if(StackEmpty(&s1))  //如果栈为空,说明没有左括号,则返回false
            {
                return false;
            }
            char ch = StackTop(&s1);     //获取栈顶元素
            StackPop(&s1);               //栈顶元素出栈
            if((*s == ')' && ch != '(')  //当前字符与栈顶元素未匹配成功,返回false
            || (*s == ']' && ch != '[')
            || (*s == '}' && ch != '{'))
            {
                return false;
            }
        }
        s++;
    }
    //有可能字符串中全是左括号,全部入栈了,所以需要判空一下,若不为空返回false
    return StackEmpty(&s1);  //检测栈是否为空
}

上面核心代码,有一个小小的问题,没有销毁栈,可能会造成内存泄漏。

我们来改进一下:用一个布尔变量 match 来记录下返回值 true / false,最后先销毁栈,再返回值。

bool isValid(char *s){
    Stack s1;
    StackInit(&s1);
    bool match = true;  //记录函数返回值
    while(*s)
    {
        if(*s == '(' || *s == '[' || *s == '{')  //当前字符为左括号
        {
            StackPush(&s1, *s);  //入栈
        }
        else  //当前字符为右括号
        {
            if(StackEmpty(&s1))  //如果栈为空,说明没有左括号,则返回false
            {
                match = false;
                break;
            }
            char ch = StackTop(&s1);     //获取栈顶元素
            StackPop(&s1);               //栈顶元素出栈
            if((*s == ')' && ch != '(')  //当前字符与栈顶元素未匹配成功,返回false
            || (*s == ']' && ch != '[')
            || (*s == '}' && ch != '{'))
            {
                match = false;
                break;
            }
        }
        s++;
    }
    //match为true,有可能因为字符串中全是左括号,全部入栈了,所以需要判空一下,若不为空返回false
    if(match == true)
    {
        match = StackEmpty(&s1);
    }
    StackDestroy(&s1);  //销毁栈
    return match;
}

大家快去动手练习一下吧!

你可能感兴趣的:(LeetCode,leetcode,算法,栈,stack,括号匹配)