一、力扣第20题:有效的括号
题目描述:
1.解题思路
我们先分析一下题目,它一共只需要匹配三种情况,() [] {}。对于字符串的的一堆括号,我们其实可以将它想象成一共栈,当字符串是( [ { 也就是左括号的时候,就入栈。当遇到右括号的时候,我们就看这个右括号是否与栈顶元素匹配,顺便把栈顶元素给取出来。如果刚好匹配,那太好了,我们可以看下一个字符,是需要入栈还是需要进行匹配。我们进行重复判断,当刚好栈为空的时候,那么也就是说明这个字符串匹配成功了。如果不匹配的话,那我们直接返回false就可以了。
2.写出代码
我们的思路全部是利用栈的,所以我们必须得先实现一个栈出来。根据我们这些思路,我们需要使用的栈操作有初始化栈、入栈、销毁栈、判断栈是否为空、取出栈顶的元素、出栈这些操作。我们先来实现一下这些操作。
如下所示,因为该题是接口型的,所以我们无需写出头文件,这是我们栈的实现。注意这里一定要自己写出来
typedef char STDateType; typedef struct Stack { STDateType* a; int top; int capacity; }Stack; //初始化栈 void StackInit(Stack* ps) { assert(ps); STDateType* tmp = (STDateType*)malloc(4*sizeof(STDateType)); if(tmp==NULL) { printf("malloc is fail\n"); exit(-1); } pa->a=tmp; ps->top=0; ps->capacity=4; } //入栈 void StackPush(Stack* ps,STDateType x) { assert(ps); //判断容量是否满了 if(ps->top==ps->capacity) { //扩容 STDateType* tmp=(STDateType*)realloc(ps->a,2 * sizeof(STDateType)* ps->capacity); if(tmp==NULL) { printf("realloc is fail\n"); exit(-1); } ps->a=tmp; ps->capacity*=2; } //入栈 ps->a[ps->top]=x; ps->top++; } //出栈 void StackPop(Stack* ps) { assert(ps); assert(ps->top>0); ps->top--; } //取出栈顶元素 STDateType StackTop(Stack* ps) { assert(ps); assert(ps->top>0); return ps->a[ps->top-1]; } //判断栈是否为空 bool StackEmpty(Stack* ps) { assert(ps); return ps->top==0; } //销毁栈 void StackDestory(Stack* ps) { assert(ps); free(ps->a); ps->a=NULL; ps->capacity=ps->top=0; }
然后接下来就是我们要开始使用栈了
使用栈的话,要特别注意几个极端情况,如只有左括号,只有右括号,等情况的处理
bool isValid(char * s) { Stack ST; StackInit(&ST); while(*s) { switch(*s) { case '(': case '[': case '{': StackPush(&ST,*s); break; case ')': case ']': case '}': { if(StackEmpty(&ST)) { StackDestory(&ST); return false; } char tmp=StackTop(&ST); StackPop(&ST); if( *s==')'&& tmp!='('|| *s==']'&& tmp!='['|| *s=='}'&& tmp!='{') { StackDestory(&ST); return false; } break; } default: break; } s++; } if(!StackEmpty(&ST)) { StackDestory(&ST); return false; } else { StackDestory(&ST); return true; } }
3.完整代码
typedef char STDateType; typedef struct Stack { STDateType* a; int top; int capacity; }Stack; //初始化栈 void StackInit(Stack* ps) { assert(ps); STDateType* tmp = (STDateType*)malloc(4*sizeof(STDateType)); if(tmp==NULL) { printf("malloc is fail\n"); exit(-1); } ps->a=tmp; ps->top=0; ps->capacity=4; } //入栈 void StackPush(Stack* ps,STDateType x) { assert(ps); //判断容量是否满了 if(ps->top==ps->capacity) { //扩容 STDateType* tmp=(STDateType*)realloc(ps->a,2 * sizeof(STDateType)* ps->capacity); if(tmp==NULL) { printf("realloc is fail\n"); exit(-1); } ps->a=tmp; ps->capacity*=2; } //入栈 ps->a[ps->top]=x; ps->top++; } //出栈 void StackPop(Stack* ps) { assert(ps); assert(ps->top>0); ps->top--; } //取出栈顶元素 STDateType StackTop(Stack* ps) { assert(ps); assert(ps->top>0); return ps->a[ps->top-1]; } //判断栈是否为空 bool StackEmpty(Stack* ps) { assert(ps); return ps->top==0; } //销毁栈 void StackDestory(Stack* ps) { assert(ps); free(ps->a); ps->a=NULL; ps->capacity=ps->top=0; } bool isValid(char * s) { Stack ST; StackInit(&ST); while(*s) { switch(*s) { case '(': case '[': case '{': StackPush(&ST,*s); break; case ')': case ']': case '}': { if(StackEmpty(&ST)) { StackDestory(&ST); return false; } char tmp=StackTop(&ST); StackPop(&ST); if( *s==')'&& tmp!='('|| *s==']'&& tmp!='['|| *s=='}'&& tmp!='{') { StackDestory(&ST); return false; } break; } default: break; } s++; } if(!StackEmpty(&ST)) { StackDestory(&ST); return false; } else { StackDestory(&ST); return true; } }
二、力扣第225题:用队列实现栈
题目链接:225. 用队列实现栈 - 力扣(Leetcode)
题目描述:
1.思路分析
我们现在有两个队列,队列的性质是先进先出,而栈的性质是先进后出。那么我们该如何实现呢?我们可以这样做,假如说这是两个队列,我们先将数据都放入一个队列中
当我们想要出去一共数据的时候,那么栈的性质是先出4。所以我们可以先将1 2 3都放入第二个队列中,然后4就可以出去了。
当我们想要插入一共数据的时候,我们直接插入到有数据的一个队列中,这样就能模拟对栈的性质了。
2.代码实现
既然要运用到队列,那么我们得先实现一下队列。才可以去使用
如下所示,是本题的队列的实现部分
typedef int QDateType; typedef struct QNode { struct QNode* next; QDateType date; }QNode; typedef struct Queue { QNode* head; QNode* tail; }Queue; //队列的初始化 void QueueInit(Queue* pq) { assert(pq); pq->head=NULL; Pq->tail=NULL; } //队列的插入 void QueuePush(Queue* pq,QDateType x) { assert(pq); //创建结点 QNode* newnode=(QNode*)malloc(sizeof(QNode)); if(newnode==NULL) { printf("malloc is fail\n"); exit(-1); } newnode->next=NULL; newnode->date=x; //第一个结点的插入 if(pq->head==NULL) { pq->head=pq->tail=newnode; } //非第一个结点的插入 else { pq->tail->next=newnode; pq->tail=newnode; } } //出队列 void QueuePop(Queue* pq) { assert(pq); assert(pq->head); //如果只有一个结点,那么tail会形成野指针 if(pq->head->next==NULL) { free(pq->head); pq->head=pq->tail=NULL; } else { QNode* second=pq->head->next; free(pq->head); pq->head=second; } } //队头的元素 QDateType QueueFront(Queue* pq) { assert(pq); assert(pq->head); return pq->head->date; } //队尾的元素 QDateType QueueBack(Queue* pq) { assert(pq); assert(pq->head); return pq->tail->date; } //队列的元素个数 int QueueSize(Queue* pq) { assert(pq); int size=0; QNode* cur=pq->head; while(cur) { size++; cur=cur->next; } return size; } //队列是否为空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head==NULL; } //队列的销毁 void QueueDestory(Queue* pq) { assert(pq); QNode* cur=pq->head; while(cur) { QNode* next=cur->next; free(cur); cur=next; } pq->head=NULL; pq->tail=NULL; }
有了这个队列,我们才可以去完成这道题。
typedef struct { Queue q1; Queue q2; } MyStack; MyStack* myStackCreate() { MyStack* ps=(MyStack*)malloc(sizeof(MyStack)); if(ps==NULL) { printf("malloc is fail\n"); exit(-1); } //初始化队列 QueueInit(&ps->q1); QueueInit(&ps->q2); return ps; } void myStackPush(MyStack* obj, int x) { if(QueueEmpty(&obj->q1)) { QueuePush(&obj->q2,x); } else { QueuePush(&obj->q1,x); } } int myStackPop(MyStack* obj) { Queue* emptyQueue=&obj->q1; Queue* noemptyQueue=&obj->q2; if(!QueueEmpty(&obj->q1)) { emptyQueue=&obj->q2; noemptyQueue=&obj->q1; } while(QueueSize(noemptyQueue) >1) { QueuePush(emptyQueue,QueueFront(noemptyQueue)); QueuePop(noemptyQueue); } int ret=QueueFront(noemptyQueue); QueuePop(noemptyQueue); return ret; } int myStackTop(MyStack* obj) { if(!QueueEmpty(&obj->q1)) { return QueueBack(&obj->q1); } else { return QueueBack(&obj->q2); } } bool myStackEmpty(MyStack* obj) { if(QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2)) { return true; } else { return false; } } void myStackFree(MyStack* obj) { QueueDestory(&obj->q1); QueueDestory(&obj->q2); free(obj); }
3.完整代码
typedef int QDateType; typedef struct QNode { struct QNode* next; QDateType date; }QNode; typedef struct Queue { QNode* head; QNode* tail; }Queue; //队列的初始化 void QueueInit(Queue* pq) { assert(pq); pq->head=NULL; pq->tail=NULL; } //队列的插入 void QueuePush(Queue* pq,QDateType x) { assert(pq); //创建结点 QNode* newnode=(QNode*)malloc(sizeof(QNode)); if(newnode==NULL) { printf("malloc is fail\n"); exit(-1); } newnode->next=NULL; newnode->date=x; //第一个结点的插入 if(pq->head==NULL) { pq->head=pq->tail=newnode; } //非第一个结点的插入 else { pq->tail->next=newnode; pq->tail=newnode; } } //出队列 void QueuePop(Queue* pq) { assert(pq); assert(pq->head); //如果只有一个结点,那么tail会形成野指针 if(pq->head->next==NULL) { free(pq->head); pq->head=pq->tail=NULL; } else { QNode* second=pq->head->next; free(pq->head); pq->head=second; } } //队头的元素 QDateType QueueFront(Queue* pq) { assert(pq); assert(pq->head); return pq->head->date; } //队尾的元素 QDateType QueueBack(Queue* pq) { assert(pq); assert(pq->head); return pq->tail->date; } //队列的元素个数 int QueueSize(Queue* pq) { assert(pq); int size=0; QNode* cur=pq->head; while(cur) { size++; cur=cur->next; } return size; } //队列是否为空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head==NULL; } //队列的销毁 void QueueDestory(Queue* pq) { assert(pq); QNode* cur=pq->head; while(cur) { QNode* next=cur->next; free(cur); cur=next; } pq->head=NULL; pq->tail=NULL; } typedef struct { Queue q1; Queue q2; } MyStack; MyStack* myStackCreate() { MyStack* ps=(MyStack*)malloc(sizeof(MyStack)); if(ps==NULL) { printf("malloc is fail\n"); exit(-1); } //初始化队列 QueueInit(&ps->q1); QueueInit(&ps->q2); return ps; } void myStackPush(MyStack* obj, int x) { if(QueueEmpty(&obj->q1)) { QueuePush(&obj->q2,x); } else { QueuePush(&obj->q1,x); } } int myStackPop(MyStack* obj) { Queue* emptyQueue=&obj->q1; Queue* noemptyQueue=&obj->q2; if(!QueueEmpty(&obj->q1)) { emptyQueue=&obj->q2; noemptyQueue=&obj->q1; } while(QueueSize(noemptyQueue) >1) { QueuePush(emptyQueue,QueueFront(noemptyQueue)); QueuePop(noemptyQueue); } int ret=QueueFront(noemptyQueue); QueuePop(noemptyQueue); return ret; } int myStackTop(MyStack* obj) { if(!QueueEmpty(&obj->q1)) { return QueueBack(&obj->q1); } else { return QueueBack(&obj->q2); } } bool myStackEmpty(MyStack* obj) { if(QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2)) { return true; } else { return false; } } void myStackFree(MyStack* obj) { QueueDestory(&obj->q1); QueueDestory(&obj->q2); free(obj); } /** * Your MyStack struct will be instantiated and called as such: * MyStack* obj = myStackCreate(); * myStackPush(obj, x); * int param_2 = myStackPop(obj); * int param_3 = myStackTop(obj); * bool param_4 = myStackEmpty(obj); * myStackFree(obj); */
总结
本小节完成了两道力扣题,20.有效的括号、225.用队列实现栈
如果对你有帮助的话,不要忘记一键三连哦!!!
想获得更多优质的内容,一定要关注我哦!!!