栈和队列算法题
在学习了栈和队列的相关概念并且在之前也实现了栈和队列,接下来我们就来试着写一些栈和队列的算法题,在这些算法题当中将会使用到之前实现的栈或者队列,栈、队列在这当中将会变为工具一样,我们就会像工具一样拿着它们去解决问题,相信通过本篇算法题的解决,你会对栈和队列有更深层次的理解,一起加油吧!!!
1.有效的括号
20. 有效的括号 - 力扣(LeetCode)
通过以上的题目描述可以看出该算法题要我们实现的是是否是有效括号进行判断,那么在实现该算法题的代码前我们先要来了解什么是有效的括号
首先有效的括号每个左括号必须要有相对应的右括号且每个右括号都有一个对应的相同类型的左括号。
例如以下的示例在以上的示例当中左括号 [ 和 ( 都有相对应的右括号 [ 和 ),这时就满足有效括号的第一个条件,但要判断是否为有效括号还需要进行其他条件的判断
有效括号的第二个条件是有效的括号一定是按之前的顺序闭合的,在此正确的闭合方式是指整体必须是对称的。在以上示例当中对称的,这就符合正确的括号闭合方式,而在以下示例当中整体就不是对称的这时就不符合正确的闭合方式
在了解了有效的括号后就来思考该如何来实现该算法题
确实在解决该算法题中我们使用到了我们之前实现的栈,首先通过遍历括号的字符串一开始如果遍历到字符是左括号就将该括号入栈;如果一开始遍历到的括号就是右括号就直接说明这不是一个有效的括号,遍历完了之后继续遍历之后的字符直到遍历到\0,在此过程中如果遍历到字符为左括号就入栈;是右括号就和取栈顶元素进行比较,若匹配就继续进行操作;不匹配就说明不为有效的括号
最终遍历完字符串后要看此时栈内是否为空,如果不为空的话就说明该字符串不为有效的括号
例如以下示例:
当字符串为以上的括号时,先遍历因为前两个都为左括号就将这两个字符入栈
之后再继续遍历原字符串由于遍历到位右括号就取栈顶元素和遍历到的字符进行匹配,这时为有效的括号就继续进行遍历
最终遍历完字符串时栈为空就说明原字符串中字符为有效的括号
在完成该算法题的分析以及示例的讲解后接下来就来实现该算法题的代码
在实现该算法题的代码前先要将之前实现的栈的结构和实现各个功能的函数导入到 isValid函数之前,之后isValid内的代码就按照我们以上的想法来实现,先定义一个栈st,之后遍历字符串进行括号的判断
当在实现以上过程中还要对两种特殊的情况进行判断,一种是当字符串中都是左括号时,这时就不会进行出栈这一操作,因此在isValid函数的最后要判断栈是否为空,为空就返回true;不为空就返回false。另一种是当字符串中都是右括号时,这时就不会有字符入栈,因此在遍历到字符是右括号时要判断栈是否为空,为空就返回false
以下是完整的代码
typedef char STDataType;
typedef struct stack
{
STDataType* a;
int capacity;
int top;
}stack;
//初始化栈
void stackInit(stack* ps)
{
assert(ps);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//销毁栈
void stackDestory(stack* ps)
{
assert(ps);
if (ps->a)
{
free(ps->a);
}
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//检测栈是否为空
bool stackEmpty(stack* ps)
{
assert(ps);
return ps->top==0;
}
//入栈
void stackPush(stack* ps,STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail!");
exit(1);
}
ps->a=tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top++] = x;
}
//出栈
void stackPop(stack* ps)
{
assert(ps);
assert(!stackEmpty(ps));
--ps->top;
}
//获取栈顶元素
STDataType stackTop(stack* ps)
{
assert(ps);
assert(!stackEmpty(ps));
return ps->a[ps->top - 1];
}
//获取栈中有效元素个数
int stackSize(stack* ps)
{
assert(ps);
return ps->top;
}
bool isValid(char* s)
{
stack st;
stackInit(&st);
char* ps=s;
while(*ps!='\0')
{
if(*ps=='('||*ps=='['||*ps=='{')//判断是否为左括号
{
stackPush(&st,*ps);
}
else//判断是否为右括号
{
if(stackEmpty(&st))
{
return false;
}
char ch=stackTop(&st);
if((*ps==')'&&ch=='(' )||(*ps==']'&&ch=='[')||(*ps=='}'&&ch=='{'))
{
stackPop(&st);
}
else
{
stackDestory(&st);
return false;
}
}
ps++;
}
bool p=stackEmpty(&st);
stackInit(&st);
return p;
}