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

cpp 复制代码
typedef int STDataType;

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

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

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

cpp 复制代码
if (*s==')'&& top=='(')
{
}

应该去判断不匹配的情况

cpp 复制代码
if (*s==')'&& top !='(') 

草稿代码

cpp 复制代码
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循环后的几行改为:

cpp 复制代码
    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函数部分)

cpp 复制代码
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.代码优化

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

cpp 复制代码
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;
}
相关推荐
地平线开发者3 小时前
J6B vio scenario sample
算法
BothSavage15 小时前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn15 小时前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法
烬羽16 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
先吃饱再说1 天前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰1 天前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 天前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六2 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程