当前位置: 首页 > article >正文

L11.【LeetCode笔记】有效的括号

目录

1.题目

2.分析

理解题意

解决方法

草稿代码

​编辑

逐一排错

1.当字符串为"["时,分析代码

2.当字符串为"()]"时,分析代码

正确代码(isValid函数部分)

提交结果

3.代码优化


1.题目

https://leetcode.cn/problems/valid-parentheses/description/

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

有效字符串需满足:

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

示例 1:

输入:s = "()"

输出:true

示例 2:

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

输出:true

示例 3:

输入:s = "(]"

输出:false

示例 4:

输入:s = "([])"

输出:true

提示:

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

2.分析

理解题意

括号能匹配应该是成对出现(像(]不为成对出现),分为两种情况:

不嵌套:()[]{}

嵌套:([])

解决方法

1.出现左括号,就将其入栈

2.出现右括号,就将其对应的左括号出栈

例如:([{}])

入栈图

有关于栈的操作函数参见97.【C语言】数据结构之栈, 但也不能完全挪用

头文件的int要改为char

typedef int STDataType;

步骤:初始化栈-->操作栈(push&pop)-->销毁栈

出栈时先取括号,再出栈,接着判断括号是否匹配.若匹配,则继续进行;若不匹配,则返回false

但if语句判断匹配的情况没有任何作用

if (*s==')'&& top=='(')
{
}

应该去判断不匹配的情况

if (*s==')'&& top !='(') 

草稿代码

typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top; 
	int capacity;
}ST;

void STInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		perror("malloc");
		return;
	}
	ps->capacity = 4;
	ps->top = 0;//top栈顶元素的下一个位置
}

void STDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));//确保不越界
	ps->top--;
}

STDataType STTop(ST* ps)//访问栈顶元素
{
	assert(ps);
	assert(!STEmpty(ps));//确保不越界
	return ps->a[ps->top - 1];
}

bool isValid(char* s) 
{
    ST st;
    STInit(&st);
    while(*s)
    {
        if (*s=='('||*s=='['||*s=='{')
        {
            STPush(&st,*s);
        }
        else
        {
            char top=STTop(&st);//注意
            STPop(&st);
            if ((*s==')'&&top !='(')
            ||(*s==']'&&top !='[')
            ||(*s=='}'&&top !='{'))
            return false;
        }
        s++;
    }
    STDestory(&st);
    return true;
}

看起来提供的测试用例的执行结果没有问题

但是当出现类似"["、"()]"等的情况时,会出错

逐一排错

1.当字符串为"["时,分析代码

进入while循环后,[入栈,s++,下一次*s==\0,结束循环,STDestory(&st);后返回true

栈不为空(有[)应该返回false,所以在循环结束后,应该用一个变量接收STEmpty的返回值

while循环后的几行改为:

    bool ret=STEmpty(&st);
    STDestory(&st);
    return ret;

但这样仍然过不了"()]"测试用例

2.当字符串为"()]"时,分析代码

断言生效STTop: Assertion `!STEmpty(ps)' failed

(入栈-->)出栈-->*s==']'时,while循环的STPush(&st,*s);不执行,当执行else的第一个语句char top=STTop(&st);时,assert(!STEmpty(ps));生效

即当栈为空时,访问栈顶元素是错误的!

在else中,先判断栈是否为空,若为空,则返回false即可

正确代码(isValid函数部分)

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 ((*s==')'&&top !='(')
            ||(*s==']'&&top !='[')
            ||(*s=='}'&&top !='{'))
            return false;
        }
        s++;
    }
    bool ret=STEmpty(&st);
    STDestory(&st);
    return ret;
}

提交结果

3.代码优化

返回前应该销毁栈,防止内存泄漏

bool isValid(char* s) 
{
    ST st;
    STInit(&st);
    while(*s)
    {
        if (*s=='('||*s=='['||*s=='{')
        {
            STPush(&st,*s);
        }
        else
        {
            if (STEmpty(&st))
            {
                STDestory(&st);//修改后
                return false;
            }
            char top=STTop(&st);
            STPop(&st);
            if ((*s==')'&&top !='(')
            ||(*s==']'&&top !='[')
            ||(*s=='}'&&top !='{'))
            {
               STDestory(&st);//修改后
               return false;           
            }
        }
        s++;
    }
    bool ret=STEmpty(&st);
    STDestory(&st);
    return ret;
}

http://www.kler.cn/a/399529.html

相关文章:

  • 帧中继原理与配置
  • 【3D Slicer】的小白入门使用指南九
  • 【项目开发】理解SSL延迟:为何HTTPS比HTTP慢?
  • 使用视频提升应用在 App Store 中的推广效果
  • IDEA leetcode插件代码模板配置,登录闪退解决
  • GoogleCloud服务器的SSH连接配置
  • 代码随想录算法训练营第四十七天|Day47 单调栈
  • 2022数学分析【南昌大学】
  • mini-jquery
  • Python数据分析NumPy和pandas(三十五、时间序列数据基础)
  • 炼码LintCode--数据库题库(级别:简单;数量:55道)--刷题笔记_02
  • C++【nlohmann/json】库序列化与反序列化
  • ALSA - (高级Linux声音架构)是什么?
  • ShardingSphere 如何完美驾驭分布式事务与 XA 协议?
  • HTTP常见的状态码有哪些,都代表什么意思
  • DB_redis数据一致性(三)
  • web3+web2安全/前端/钱包/合约测试思路——尝试前端绕过直接上链寻找漏洞
  • @bytemd/vue-next Markdown编辑器的使用
  • Linux下MySQL的简单使用
  • 定时器(QTimer)与随机数生成器(QRandomGenerator)的应用实践——Qt(C++)
  • Linux中的挂载
  • vue 自定义指令( 全局自定义指令 | 局部自定义指令 )
  • 深度学习之GAN的生成能力评价
  • Windows C++ TCP/IP 两台电脑上互相传输字符串数据
  • 【Linux学习】【Ubuntu入门】1-4 ubuntu终端操作与shell命令1
  • 数据驱动的期货市场决策:民锋科技的量化分析创新