LeetCode每日一练 —— 20. 有效的括号

本文通过栈的数据结构解析LeetCode第20题——有效括号。通过遍历输入字符串,遇到左括号入栈,遇到右括号时检查与栈顶左括号是否匹配,最后判断栈是否为空来确定括号是否有效。代码使用C++实现,通过STL简化栈的操作。
摘要由CSDN通过智能技术生成

🌟 前言

Wassup guys!我是Edison 😎

今天是 LeetCode 上的 leetcode 20. 有效的括号

Let’s get it!

在这里插入图片描述



1. 题目描述

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。
 
有效字符串需满足:
 
1、左括号必须用相同类型的右括号闭合。
 
2、左括号必须以正确的顺序闭合。

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

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

示例 5:

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

2. 思路分析

是一种 先进后出 的数据结构,处理括号问题的时候尤其有用。

思路:

(1)遇到左括号,就入栈
 
(2)遇到右括号,就去栈中寻找最近的左括号,看是否匹配,然后出栈

步骤:

遍历字符串,遇到前括号直接入栈。
 
遇到后括号,判断该后括号与栈顶的前括号是否匹配(若此时栈为空,则字符串无效),若不匹配则字符串无效;
 
若匹配则删除栈顶元素,继续遍历字符串,直到字符串遍历完毕。
 
当字符串遍历完后,检测栈是否为空,若为空,则字符串有效,若不为空,说明有前括号未匹配,字符串无效。

3. 代码实现

这道题如果用 C 实现的话,就需要我们自己去写一个栈;

而如果用 C++ 实现的话,直接用 STL 即可;

接口代码

typedef char STDataType;

// 支持动态增长的栈
typedef struct Stack
{
	STDataType* a;
	int top; //栈顶
	int capacity; //容量
}ST;

//初始化栈
void StackInit(ST* ps);

//入栈
void StackPush(ST* ps, STDataType x);

//出栈
void StackPop(ST* ps);

//获取栈顶元素
STDataType StackTop(ST* ps);

// 获取栈中有效元素个数
int StackSize(ST* ps);

//检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(ST* ps);

//销毁栈
void StackDestroy(ST* ps);

//————————————————————————————————————————————————————————————————

//初始化栈
void StackInit(ST* ps) {
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

//入栈
void StackPush(ST* ps, STDataType x) {
	assert(ps);

	//满了扩容
	if (ps->top == ps->capacity) {
		int newCapacity = ps->capacity == (0) ? (4) : (ps->capacity * 2);
		ps->a = realloc(ps->a, newCapacity * sizeof(STDataType));
		if (ps->a == NULL) {
			printf("realloc fail\n");
			exit(-1);
		}
		ps->capacity = newCapacity;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

//出栈
void StackPop(ST* ps) {
	assert(ps);
	assert(ps->top > 0);
	--ps->top;
}

//获取栈顶元素
STDataType StackTop(ST* ps) {
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

// 获取栈中有效元素个数
int StackSize(ST* ps) {
	assert(ps);

	return ps->top;
}

//检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(ST* ps) {
	assert(ps);

	//如果top等于0,就是空
	return ps->top == 0;
}

//销毁栈
void StackDestroy(ST* ps) {
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

//————————————————————————————————————————————————————————————————

bool isValid(char * s){
    ST st; //先定义一个栈
    StackInit(&st);

    while (*s)
    {
        //如果是左括号,就入栈
        if (*s == '[' || *s == '(' || *s == '{') {
            StackPush(&st, *s); //把左括号放入栈里面
            ++s;
        }
        else { //出栈
            /*假设只输入了一个']',那么就会进行出栈判断;
            因为输入的是右括号,直接到这里进行判断,那么栈肯定为空,所以直接return false
            */
            if (StackEmpty(&st)) {
                return false;
            }
            char top = StackTop(&st); //把栈顶的左括号拿出来,放到top中
            StackPop(&st); 

            if (*s == ']' && top != '[') {
                StackDestroy(&st);
                return false;
            }
            else if (*s == ')' && top != '(') {
                StackDestroy(&st);
                return false;
            }
            else if (*s == '}' && top != '{') {
                StackDestroy(&st);
                return false;
            }
            else { //说明匹配了
                ++s; //匹配,继续比
            }
        }
    }

    //栈为空,说明所以左括号都匹配了
    //栈不为空,就false,栈为空,就是true
    bool ret = StackEmpty(&st);
    
    StackDestroy(&st); //销毁栈
    
    return ret;
}

提交结果
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Albert Edison

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

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

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

打赏作者

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

抵扣说明:

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

余额充值