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;
}
相关推荐
亦枫Leonlew4 分钟前
微积分复习笔记 Calculus Volume 2 - 5.1 Sequences
笔记·数学·微积分
飞飞-躺着更舒服6 分钟前
【QT】实现电子飞行显示器(改进版)
开发语言·qt
武昌库里写JAVA22 分钟前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
爱码小白37 分钟前
网络编程(王铭东老师)笔记
服务器·网络·笔记
ZSYP-S1 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos1 小时前
c++------------------函数
开发语言·c++
yuanbenshidiaos1 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习1 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
程序员_三木1 小时前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
LuH11241 小时前
【论文阅读笔记】Learning to sample
论文阅读·笔记·图形渲染·点云