有效的括号
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([])"
输出:true
思路:借助数据结构——栈,遍历字符串,左括号入栈,遇到右括号就与栈顶元素比较是否匹配
具体过程:首先括号需要对应闭合,可以联想到栈(后进先出),例如 s = " () [] {} " 用pi进行遍历,如果是左括号则让其入栈,只要是右括号就用栈顶元素与pi指向的字符串进行比较,是否是匹配的右括号,如果匹配,就让其出栈。
代码如下:前面部分是栈的实现,后面调用对应函数
//定义栈的结构
typedef char STDataType;
typedef struct Stack
{
STDataType* arr;
int top; //指向栈顶的位置
int capacity; //容量
}ST; //用ST表示栈
//初始化栈
void STInit(ST* ps)
{
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//销毁栈
void STDestroy(ST* ps)
{
if (ps->arr)
free(ps->arr);
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//入栈----往栈顶插入数据
void StackPush(ST* ps, STDataType x)
{
if (ps->top == ps->capacity)
{
assert(ps);
//空间不够----增容
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
//创建临时变量tmp接收realloc的返回值
STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
if (tmp == NULL)//如果扩容失败,返回一个不为零的值退出
{
perror("realloc fail");
exit(1);
}
ps->arr = tmp;
ps->capacity = newCapacity;
//空间足够
}
ps->arr[ps->top] = x;
ps->top++;
}
//若栈为空,则返回0
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
//出栈---从栈顶出去
void StackPop(ST* ps)
{
assert(!StackEmpty(ps));//如果栈为空就不能删除,所以栈不能为空
--ps->top;
}
//取栈顶数据
STDataType StackTop(ST* ps)
{
assert(!StackEmpty(ps));
return ps->arr[ps->top - 1];
}
//获取栈中有效元素个数
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
//
bool isValid(char* s)
{
ST st;
STInit(&st);
//遍历给定的字符串s
char* pi = s;
while(*pi != '\0')
{
//左括号入栈
if(*pi == '(' || *pi == '[' || *pi == '{')
{
StackPush(&st,*pi);//调用入栈操作
}
else
{
//右括号取栈顶并匹配
//判断栈是否为空
if(StackEmpty(&st))
{
STDestroy(&st);
return false;
}
char top = StackTop(&st);//top接收栈顶元素,数据类型是char
if((top == '(' && *pi != ')') || (top == '[' && *pi != ']')
||(top == '{' && *pi != '}'))
{
STDestroy(&st);
return false;
}
StackPop(&st);//旧的栈顶元素出栈,top继续往下走
}
pi++;//pi继续往后遍历
}
//返回true之前再判断一下栈是否为空,避免‘()[’这种类似情况出现
//如果栈为空,说明所有的左括号都已经匹配完了,反之非有效字符串
bool ret = StackEmpty(&st) ? true : false;
STDestroy(&st);
return ret;
}