目录
题目:
思路分析:
解题思路:
一、配对:
二、数量问题:
三、细节问题:
完整代码:
手撕栈:

题目:
给定一个只包括
'(',')','{','}','[',']'的字符串s,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
 - 左括号必须以正确的顺序闭合。
 - 每个右括号都有一个对应的相同类型的左括号。
 
题源:20. 有效的括号 - 力扣(LeetCode)
 
思路分析:
- 本题有两个难点,第一个匹配问题,第二个数量问题。
 - 如果匹配有一对匹配失败,需要返回false,如果数量过多或则数量过少,也需要返回false
 - 其次,我们应该如何配对?怎么配对?怎么样才能知道数量的过多或是过少?
 
解题思路:
在面对这种问题时,可以采取栈的方式进行运算。
首先,需要手撕一个能够存储括号的栈,其次利用栈内的操作方式进行操作。
其次,根据题目交给的代码,进行接下来的操作。

一、配对:
题目的要求是 ( 与 ) 、{ 与 } 、[ 与 ] 、进行对应的配对, 那么使用栈的插入操作,将左括号 (、{ 、[ 进行存储,而右括号进行与入栈的左括号进行配对。

二、数量问题:
数量问题在上一个问题的解答下可以分为两种:
- 左括号过多,右括号少,导致剩余的括号数量多了。
 - 右括号过多,左括号少,导致匹配的次数少了。
 
同时,又可以把两个问题变成一个,那就是左括号过多时,左括号过少时,栈内的情况如何?
如果左括号过多,那么就表示匹配结束后栈内不为空,如果左括号过少,在匹配时,栈内就为空。
所以,需要在匹配的过程中,以及匹配结束后,进行栈内是否为空的判断!
 
三、细节问题:
输入的字符是根据ASCII数值进行判断的,因为题目是输入一串字符串,且字符串一定会带有结束标语,也就是\0,\0的ASCII值是0,所以这里的循环直接使用*s没有问题!
 
在循环的末尾中,需要进行++s,表示字符串中的下一个字符开始输入,并进入循环。

完整代码:
 
手撕栈:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 标识栈顶下一个位置
	int capacity;
}ST;
//栈的初始化
void STInit(ST* pst);
//栈的销毁
void STDestroy(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;
	pst->capacity = 0;
	pst->top = 0;
}
//销毁栈
void STDestroy(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 newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	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);
	/*if (pst->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}*/
	return pst->top == 0;
}
//获取栈的有效元素个数
int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}
                










![[数据结构]—带头双向循环链表——超详解](https://img-blog.csdnimg.cn/58792a038bb845b6bbe1c21dea9d0bec.png)







