Leetcode-有效的括号(带图)

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/

题目

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

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"
输出:true

示例 2:

输入:s = "()[]{}"
输出:true

示例 3:

输入:s = "(]"
输出:false

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

图解

代码(思路都在代码中)

typedef char STDataType;
// 栈的结构
typedef struct Stack {
    STDataType* a; // 指针
    int top;       // 栈顶
    int capacity;  // 容量
} Stack;
// 扩容函数
void Exp(Stack* p) {
    if (p->capacity == p->top) {
        // 利用三目运算来判断是否
        int New_cap = p->capacity == 0 ? 4 : p->capacity * 2;
        STDataType* tmp =
            (STDataType*)realloc(p->a, New_cap * sizeof(STDataType));
        if (tmp == NULL) {
            assert("realloc");
            return;
        }
        // 将开辟空间给给原来的变量
        p->a = tmp;
        p->capacity = New_cap;
    }
}

// 初始化
void StackInit(Stack* p) {
    assert(p);
    p->a = NULL;
    p->capacity = p->top = 0;
}
// 入栈
void StackPush(Stack* p, STDataType data) {
    assert(p);
    // 判断空间
    Exp(p);
    // 入栈
    p->a[p->top] = data;
    // 入栈后栈顶向上移动
    p->top++;
}
// 出栈
void StackPop(Stack* p) {
    assert(p);
    assert(p->top > 0); // 确保不为空

    // 判断是否元素是否为0,避免越界
    /*if (p->top == 0)
    {
        return;
    }*/
    p->top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* p) {
    // 判断是否为0
    if (p->top == 0) {
        return (STDataType)0; // 由于返回类型是 STDataType,所以需要强制转换
    }
    return p->a[p->top - 1];
}
// 获取栈中有效元素个数
int StackSize(Stack* p) { return p->top; }
// 判空
bool StackEmpty(Stack* p) {
    // 使用逻辑非操作符(!)来检查栈顶指针(top)是否为0(即栈是否为空)
    // 如果top为0,说明栈中没有任何元素,因此栈是空的
    // 在C语言中,逻辑非操作符会将0转换为1(true),非0转换为0(false)
    // 所以当栈顶指针top为0时,!p->top的结果为true(非零值),表示栈为空
    // 反之,如果栈中有元素(top非0),则!p->top的结果为false(0),表示栈非空
    return !p->top;
}
// 销毁栈
void StackDestroy(Stack* p) {
    if (p->a) {
        free(p->a);
        p->a = NULL;
        p->capacity = p->top = 0;
    }
}
bool isValid(char* s) {
    // 思路:我们利用栈来解决这个问题,利用进先出的特性
    // 创建栈
    Stack s1;
    // 初始化栈
    StackInit(&s1);
    // 利用循环来遍历字符
    while (*s) {
        // 让左括号入栈
        if (*s == '(' || *s == '{' || *s == '[' ) {
            StackPush(&s1, *s);
        } else { // 右括号取栈顶的左括号匹配

            // 首先我们判断是否为空
            if (StackEmpty(&s1)) { // 这里说明栈我为空(也就是说左括号没有和右括号对应或者说就只有一个右括号)
                StackDestroy(&s1); // 直接释放栈
                return false;
            }
            // 获取栈顶元素(这里就有了后进先出的原理了)
            STDataType top = StackTop(&s1);
            // 获取后出栈,方便下一次入栈
            StackPop(&s1);
            // 判断是否对应(这边判断的条件是不相等,这样就可以排除所有可能false)

     if ((top == '{' && *s != '}')||(top == '[' && *s != ']')||(top == '(' && *s != ')'))
            // 也就是说:栈里面的左括号&&字符中不等于和他对应的右括号
             {
                return false;
                StackDestroy(&s1);
            }
        }
        ++s; // 每次遍历向后移动
    }
    // 循环跳出就意味着排除了这些可能,但是这边我们不排除只有一个左括号或者右括号或者左括号比右括号多,所以需要判空
    bool ret = StackEmpty(&s1);
    StackDestroy(&s1); // 这边我们需要释放一下,避免空间泄露
    return ret;
}

  • 35
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

普通young man

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值