一、知识点
- 栈(Stack)
规则:先进后出
想象:往箱子放书本,先放进去的在最底下,只能先拿最后放进去的。
操作:入栈 push:元素放到栈顶
出栈 pop:取出栈顶元素
取栈顶 top:查看栈顶,不删除
empty:判断栈是否为空
重点:所有操作只允许在栈顶进行,不能直接访问中间元素。
- 队列(Queue)
规则:先进先出
想象:排队打饭,先来的人先办理。
操作:
入队 push:队尾加入元素
出队 pop:队头移除元素
front 获取队头、back 获取队尾
重点:一头进、另一头出。
- 经典模型 1:括号匹配(栈最典型应用)
核心思想:遇到左括号 ( { [ 直接入栈
2:遇到右括号:栈为空 → 直接不匹配
取出栈顶,如果和当前右括号成对,栈顶出栈;否则匹配失败
3:遍历结束,栈必须是空才算全部匹配成功
关键点:最近打开的括号最先闭合,完美契合栈 先进后出。
- 经典模型 2:消消乐模型(相邻元素消除)
核心思想:遍历每一个元素,和栈顶对比
和栈顶相同:栈顶弹出(消除)
和栈顶不同:当前元素压入栈。遍历完成,栈里面剩下的就是消除之后的结果
典型题目:删除相邻重复项
二、题目
有效的括号(括号匹配栈)
思路:
1、创建栈保存左括号
2、逐个遍历字符串字符
左括号:入栈
右括号:
栈空 → 直接 false
取出栈顶,判断是否配对;配对成功出栈,失败返回 false
3、循环结束,栈空代表全部匹配,否则 false

整体答案:

1、函数定义。s 传入括号字符串;返回 1 代表有效,0 无效。

2、strlen计算字符串长度。用来确定栈需要开辟多大空间。

3、动态分配内存,用数组模拟栈。
最坏情况全是左括号,栈最大长度等于字符串长度。
4、栈标记。
top:下一个可以存放元素的空位下标。
top = 0 → 栈为空;栈顶有效元素下标永远是 top - 1。

5、循环,逐个遍历字符串里面每一个字符。i是字符串下标。

6、取出当前遍历到的字符,存入ch方便后面判断。
7、读到左括号(,不存左括号,存入它对应的右括号)。
stacktop = ')',随后top++,栈标记往后移动。
8、读到,往栈存入对应的。
9、读到{,往栈存入对应的}。

10、上面三个都不成立,说明当前字符是右括号 ) ] },进入匹配逻辑。

11、|| 只要任意一个成立,匹配失败。
top == 0:栈是空,没有左括号和当前右括号配对。
stacktop-1 != ch:栈顶保存的预期右括号 和 当前字符不一致,括号类型不匹配。
12、内存释放。函数提前 return,必须手动释放 malloc 开辟空间,防止内存泄漏
13、返回 0,表示括号字符串无效。
14、代码走到这里代表匹配成功。
top-- 逻辑上将栈顶元素弹出,完成一对括号抵消。

15、整个字符串遍历结束后执行。
top == 0:栈里面所有元素全部弹出,所有左括号都找到配对 ans=1;
栈里面还有剩余元素,代表左括号多了,没有右括号闭合 ans=0。
16、遍历正常结束,释放栈内存。
17、返回最终结果。
