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;
}
相关推荐
jingling555几秒前
面试版-前端开发核心知识
开发语言·前端·javascript·vue.js·面试·前端框架
满分观察网友z15 分钟前
开发者的“右”眼:一个树问题如何拯救我的UI设计(199. 二叉树的右视图)
算法
m0_6873998419 分钟前
写一个Ununtu C++ 程序,调用ffmpeg API, 来判断一个数字电影的视频文件mxf 是不是Jpeg2000?
开发语言·c++·ffmpeg
Natsume171022 分钟前
嵌入式开发:GPIO、UART、SPI、I2C 驱动开发详解与实战案例
c语言·驱动开发·stm32·嵌入式硬件·mcu·架构·github
爱上语文29 分钟前
Redis基础(5):Redis的Java客户端
java·开发语言·数据库·redis·后端
A~taoker35 分钟前
taoker的项目维护(ng服务器)
java·开发语言
萧曵 丶38 分钟前
Rust 中的返回类型
开发语言·后端·rust
shaun20011 小时前
华为c编程规范
c语言
hi星尘1 小时前
深度解析:Java内部类与外部类的交互机制
java·开发语言·交互
看到我,请让我去学习1 小时前
Qt编程-qml操作(js,c++,canvas)
开发语言·qt