有效的括号--力扣经典面试题

发布于:2024-05-07 ⋅ 阅读:(30) ⋅ 点赞:(0)

目录

引言

题目描述:

思路分析:

代码展示:


引言

这道题是关于栈的经典面试题,如果大家对栈这个数据结构不是很了解的话,可以先看这篇博客--数据结构之栈的超详细讲解-CSDN博客

题目描述:

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

有效字符串需满足:

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

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

思路分析:

这是一道很经典的问题,他要求我们对括号进行匹配,这里用其他方法不是很好做,但时用栈这个结构的话,能很轻松的解决.

 这里我们写一个很复杂但是匹配的例子,比如[{()}]

我们用栈来存储所有的左括号,用栈顶元素与右括号进行匹配,这里巧妙使用了栈的后进先出的特性,栈顶元素即为最后一个左括号,与最开始的右括号进行匹配,最后当我们的字符数组没有元素时即为匹配成功.

代码展示:

因为这里需要使用栈这个数据结构,我们这里是使用C语言进行编写,没有C++STL容器可以直接使用,所以需要我们手动实现,大家如果还不会的,可以看数据结构之栈的超详细讲解-CSDN博客这篇博客,这里就不再另外进行讲解

代码如下:


//栈的结构
typedef char STDataType;

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

//函数的声明
//初始化和销毁
void STInit(ST* pst);
void STDestory(ST* pst);
//入栈和出栈
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
//取栈顶元素
STDataType STTop(ST* pst);
//判空
bool STEmpty(ST* pst);
//获取数据个数
int STSize(ST* pst);

//初始化和销毁
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	//top指向栈顶数据的下一个位置
	pst->top = 0;

	//top指向栈顶数据
	//pst->top = -1;
	pst->capacity = 0;
}
void STDestory(ST* pst)
{
	assert(pst);

	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}
//入栈和出栈
void STPush(ST* pst, STDataType x)
{
	assert(pst);
	//扩容
	if (pst->top == pst->capacity)
	{
		int newcapcacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapcacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapcacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}
//取栈顶元素
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);

	return pst->a[pst->top - 1];
}
//判空
bool STEmpty(ST* pst)
{
	assert(pst);

	return pst->top == 0;
}
//获取数据个数
int STSize(ST* pst)
{
	assert(pst);

	return pst->top;
}

 代码:


//栈的结构
typedef char STDataType;

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

//函数的声明
//初始化和销毁
void STInit(ST* pst);
void STDestory(ST* pst);
//入栈和出栈
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
//取栈顶元素
STDataType STTop(ST* pst);
//判空
bool STEmpty(ST* pst);
//获取数据个数
int STSize(ST* pst);

//初始化和销毁
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	//top指向栈顶数据的下一个位置
	pst->top = 0;

	//top指向栈顶数据
	//pst->top = -1;
	pst->capacity = 0;
}
void STDestory(ST* pst)
{
	assert(pst);

	free(pst->a);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}
//入栈和出栈
void STPush(ST* pst, STDataType x)
{
	assert(pst);
	//扩容
	if (pst->top == pst->capacity)
	{
		int newcapcacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapcacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapcacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}
//取栈顶元素
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);

	return pst->a[pst->top - 1];
}
//判空
bool STEmpty(ST* pst)
{
	assert(pst);

	return pst->top == 0;
}
//获取数据个数
int STSize(ST* pst)
{
	assert(pst);

	return pst->top;
}

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(top == '(' && *s != ')'
            || top == '{' && *s != '}'
            || top == '[' && *s != ']')
            {
                STDestory(&st);
                return false;
            }
        }
        ++s;
    }
    //如果栈不为空,说明左括号必右括号多
    bool ret = STEmpty(&st);
    STDestory(&st);
    return ret;
}

我们重点看后面这个函数,我们先定义栈这个结构,然后进行初始化,当字符数组中有元素时,就进行循环,如果这个字符等于左括号时,将它入栈,否则取栈顶元素与第一个不为左括号的元素进行匹配,如果不匹配直接返回false,注意: 此时返回false时,要销毁我们的栈空间,否则会造成空间浪费.如果匹配成功,字符往下移动,进入下一轮匹配.

注意:

这里最后一定要进行判空处理

力扣中有这样一个例子: S = "{",字符数组中只有一个左括号,我们循环将它入栈后,直接结束,循环过程没有匹配失败,但这并不代表它是匹配的,所以最后进行判空处理,并销毁栈空间.