本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。
示例 1: 输入:s = "()" 输出:true
示例 2: 输入:s = "()[]{}" 输出:true
示例 3: 输入:s = "(]" 输出:false
示例 4: 输入:s = "([)]" 输出:false
示例 5: 输入:s = "{[]}" 输出:true
提示: 1 <= s.length <= 104 s 仅由括号 '()[]{}' 组成
【链接】
【思路】
数括号能不能数出来呢?不行,"([)]"的数量符合要求但括号的种类不匹配。
让我们换一种思路,运用我们学到的栈。遇到左括号就入栈,遇到右括号就出栈,栈是后进先出的,出栈出的是最近入进去的括号,如果都可以匹配上,就返回“true”,否则返回“false”。
思路就这捋顺了,接下来就要写代码了。但问题来了,从哪能搞来栈用呢?因为我们还没学到C++在这就只能憋屈得自己写个栈了,我上一篇文章<数据结构>你分得清栈和队列吗?写的栈直接复制过来用,这就是为什么参考代码那么长,其实新东西只有最后那一点。
在此强调一下,一定要保证栈的代码正确再使用,否则会bug重重,很难改。
【参考代码】
typedef int STDataType;
typedef struct Stack
{
int* a;
int top;//栈顶的位置
int capacity;//容量
}ST;
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void StackDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
//满了扩容
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
ps->a = (STDataType*)realloc(ps->a, newCapacity*sizeof(STDataType));
if (ps->a == NULL)
{
printf("realloc fail");
exit(-1);
}
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void StackPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
STDataType StackTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
int StackSize(ST* ps)//元素个数
{
assert(ps);
return ps->top;
}
bool isValid(char * s){
ST st;
StackInit(&st);
while(*s)
{
if(*s == '{'||*s == '['||*s == '(')
{
StackPush(&st, *s);
s++;
}
else
{
if(StackEmpty(&st))//防越界
return false;
char top = StackTop(&st);
StackPop(&st);
if((*s == '}' && top != '{')
||(*s == ']' && top != '[')
||(*s == ')' && top != '('))
{
StackDestory(&st);
return false;
}
s++;
}
}
bool ret = StackEmpty(&st);
StackDestory(&st);
return ret;
}