目录
题目:
思路分析:
解题思路:
一、配对:
二、数量问题:
三、细节问题:
完整代码:
手撕栈:
题目:
给定一个只包括
'('
,')'
,'{'
,'}'
,'['
,']'
的字符串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;
}