赞
踩
目录
https://leetcode.cn/problems/valid-parentheses/submissions/551394950/
思路:把左括号放到栈里,取出来栈顶和右括号匹配,匹配上了就出栈,然后在取出栈顶和下一个右括号匹配,一直匹配下去,
创建一个栈用来存放左括号,然后把字符串的首地址s给ps,让ps遍历到\0。
来看看循环里面,
第一步:判断把左括号全部放进栈里。
第二步:判断栈里是不是空,是空就没必要匹配了,没有左括号,直接返回false。
第三步:走到第三步,说明左括号全部放进栈里了,然后取出栈顶给ch,
然后左括号和右括号进行匹配,匹配成功就出栈,匹配不成功就销毁,然后返回false。
解决只有一个左括号的情况。
布尔判断栈里是不是空,是空把true给tab,不是空返回false给tab。
销毁空间后,返回tab。
- typedef char data;
- typedef struct stack
- {
- data* arr;
- int koj;//空间大小
- int top;//栈顶
- }SL;
-
- //初始化
- void csh(SL* r)
- {
- r->arr = NULL;
- r->koj = r->top = 0;
- }
-
- //入栈
- void push(SL* r, data x)
- {
- //判断空间够不够
- if (r->koj == r->top)
- {
- int koj1 = r->koj == 0 ? 4 : 2 * r->koj;
- SL* tab = (SL*)realloc(r->arr, koj1 * sizeof(SL));
- if (tab == NULL)
- {
- perror("realloc");
- exit(1);
- }
- r->arr = tab;
- r->koj = koj1;
- }
-
- r->arr[r->top] = x;
- r->top++;
- }
-
- bool buer(SL* r)
- {
- assert(r);
- return r->top == 0;
- }
-
- //出栈
- void pop(SL* r)
- {
- assert(r);
- assert(!buer(r));
- --r->top;
- }
- //取栈顶
- data qzd(SL* r)
- {
- assert(r);
- assert(!buer(r));
- return r->arr[r->top-1];
- }
- //取有效个数
- data size(SL* r)
- {
- assert(r);
- return r->top;
- }
-
- //销毁
- void xiaoh(SL* r)
- {
- assert(r);
- if (r->arr != NULL)
- {
- free(r->arr);
- }
- r->arr = NULL;
- r->koj = r->top = 0;
- }
- //上面是栈需要的函数
-
-
-
- //下面是实现代码
- bool isValid(char* s) {
- //创建一个栈
- SL add;
- //把s给ps
- char*ps=s;
-
-
- //循环让ps往后走
- while(*ps!='\0')
- {
- //判断把左括号放进栈里
- if(*ps=='(' || *ps=='[' || *ps=='{')
- {
- push(&add,*ps);
- }
- else
- {
- //判断栈顶是不是空,是空返回false。
- if(buer(&add))
- {
- return false;
- }
- //取出左括号放进ch来
- char ch = qzd(&add);
- //判断左括号和右括号匹不匹配
- if((*ps==')'&&ch=='(')
- ||( *ps==']'&&ch=='[')
- || (*ps=='}'&& ch=='{'))
- {
- //匹配出栈
- pop(&add);
- }
- else
- {//不匹配直接销毁返回false
- xiaoh(&add);
- return false;
- }
- }
- ps++;
- }
- //布尔判断栈里是不是为空,是空把true赋值给tab。
- char tab = buer(&add) == true;
- xiaoh(&add);
- return tab;
- }
https://leetcode.cn/problems/implement-stack-using-queues/description/
实现前先导入队列的函数
思路:创建2个队列
入栈不为空的队列Q1。
出栈的话把Q1的size-1的数据1和2插入Q2的队列,我们就可以把3出栈了。
https://leetcode.cn/problems/implement-stack-using-queues/
第一步:先创建2个队列来实现栈。
第二步:创建ps指向栈,然后初始化这2个队列。
入栈,为不为空的队列,入数据到队列。
if用布尔判断Q1队列是不是空,是空往Q2队列入数据,调用入队列函数。
第一步:把Q1给空队列,把Q2给不为空的队列。
第二步:判断Q1如果不为空,2个交换,把Q1给buko,把Q2给ko。
第三步:循环把有效个数-1的数据,给到为空的队列。
取出队头数据给tab,然后入队到空队列,再把不为空的队列出队。
第四步:把队列的最后一个数据,保存到pop,然后出队列,返回pop。
布尔判断,找不为空的队列,取出队尾数据,返回队尾。
布尔判断2个队列是不是空,2个都为真返回true,有1个或2个为假,返回false。
销毁直接调用销毁队列的函数就行了,然后把obj销毁,把obj置为NULL。
- typedef int data;
- typedef struct queuedata//单链表
- {
- data arr;//存放的数据
- struct queuedata* p;//指向下一个节点
- }queuedata;
-
- typedef struct Queue
- {
- queuedata* to; //队头——单链表的 头节点
- queuedata* wei;//队尾——单链表的 尾节点
- int size; //有效个数
- }Queue;
-
- //初始化
- void csh(Queue* r)
- {
- assert(r);
- r->to = r->wei = NULL;
- r->size = 0;
- }
-
- //入队尾
- void dui_wei(Queue* r,data x)
- {
- assert(r);
- //申请单链表空间
- queuedata* tab = (queuedata*)malloc(sizeof(queuedata));
- if (tab == NULL)
- {
- perror("malloc");
- exit(1);
- }
- //把x赋值给新申请空间的arr
- tab->arr = x;
- tab->p = NULL;
-
- //入队
- //判断队尾是不是空
- if (r->wei == NULL)
- {
- //是空,队头队尾指向新申请的空间
- r->to = r->wei = tab;
- }
- else//不是空
- {
- //队尾p指向新申请的空间
- r->wei->p = tab;
- //队尾走到新申请的空间
- r->wei = r->wei->p;
- }
- //有效个数加1
- r->size++;
- }
- //布尔类型
- bool buer(Queue* r)
- {
- assert(r);
- return r->to == NULL;
- }
-
- //出队,头
- void dui_to(Queue* r)
- {
- assert(r);
- //布尔类型,!把真变假,把假变真
- assert(!buer(r));
- //判断队头等于队尾,就说明只有一个节点
- if (r->to == r->wei)
- {
- //直接释放空间
- free(r->to);
- //把队头和队尾置为空
- r->to = r->wei = NULL;
- }
- else
- {
- //把队头的下一个节点给tab
- queuedata* tab = r->to->p;
- //释放当前队头节点
- free(r->to);
- //把tab节点给队头
- r->to = tab;
- }
- //有效个数减1
- --r->size;
- }
-
-
-
- //取队头数据
- data qto(Queue* r)
- {
- assert(r);
- assert(!buer(r));
- return r->to->arr;
- }
-
-
- //取尾
- data qwei(Queue* r)
- {
- assert(r);
- assert(!buer(r));
- return r->wei->arr;
- }
-
-
- //有效个数
- data size(Queue* r)
- {
- assert(r);
- return r->size;
- }
-
- //销毁
- void xiaoh(Queue* r)
- {
- assert(r);
- //assert(!buer(r));
- //把队头给tab
- queuedata* tab = r->to;
- //循环销毁单链表
- while (tab != NULL)
- {
- //add保存头节点的下一个节点
- queuedata* add = tab->p;
- //释放头节点
- free(tab);
- //把add给tab
- tab = add;
- }
- //把队头和队尾置为空
- r->to = r->wei = NULL;
- //有效个数赋值为0
- r->size = 0;
- }
- //上面是队列的函数
-
-
- /
-
-
- //下面是实现代码
- typedef struct {
- //创建2个队列来实现栈
- Queue Q1;
- Queue Q2;
-
- } MyStack;
-
- //栈初始化
- MyStack* myStackCreate()
- {
- //创建ps指向栈
- MyStack*ps=(MyStack*)malloc(sizeof(MyStack));
- //初始化这2个队列
- csh(&ps->Q1);
- csh(&ps->Q2);
- return ps;
- }
-
- //入栈
- void myStackPush(MyStack* obj, int x) {
- //往不为空的队列插入数据
- if(!buer(&obj->Q1))
- {
- dui_wei(&obj->Q1, x);
- }
- else
- {
- dui_wei(&obj->Q2, x);
- }
- }
-
-
- //出栈
- int myStackPop(MyStack* obj) {
- //空
- Queue* ko = &obj->Q1;
- //不为空
- Queue* buko = &obj->Q2;
- //找不为空的队列
- if(!buer(&obj->Q1))
- {
- buko = &obj -> Q1;
- ko = &obj -> Q2;
- }
- //把有数据的队列中size-1个数据导入到空队列中
- while(size(buko) > 1)
- {
- //取队头给tab
- int tab = qto(buko);
- //把tab的数据给 ko空队列
- dui_wei(ko , tab);
- //出队,头
- dui_to(buko);
- }
- //不为空的队列还剩下一个数据,给pop
- int pop = qto(buko);
- //最后一个数据出栈
- dui_to(buko);
- //返回pop
- return pop;
- }
-
-
- //取栈顶元素
- int myStackTop(MyStack* obj) {
-
- //找不为空的队列,取出队尾数据
- if(!buer(&obj->Q1))
- {
- return qwei(&obj->Q1);
- }
- else
- {
- return qwei(&obj->Q2);
- }
- }
-
-
-
- bool myStackEmpty(MyStack* obj) {
- //用布尔判断2个队列是不是空
- return buer(&obj->Q1) && buer(&obj->Q2);
- }
-
- //销毁
- void myStackFree(MyStack* obj) {
- //直接调用销毁队列的函数就行了
- xiaoh(&obj->Q1);
- xiaoh(&obj->Q2);
- //把我们申请的ps销毁,obj就是ps,返回了ps然后obj接收。
- free(obj);
- //置为空
- obj=NULL;
- }
-
- /**
- * 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);
- */
https://leetcode.cn/problems/implement-queue-using-stacks/description/
实现前先导入栈的函数
思路:用2个栈Q1,Q2,
入队列:往Q1导入数值,
出队列(头):判断Q2是不是空,是就循环取出Q1栈顶,导入到Q2,Q2再出栈,出的就是队头了,对了还要先保存队头,再返回队头的数据。
取队头数据:判断Q2是不是空,不是空就说明数据已经导入到Q2了,直接取栈顶。
myQueueEmpty:判断队列是不是空。
销毁:调用销毁函数,销毁2个栈,再把申请的obj空间释放,然后置为空。
第一步:创建2个栈。
第二步:创建ps空间指向Q1和Q2,
然后初始化这2个栈,返回ps。
直接调用,入栈函数,为Q1导入数据就行了。
判断Q2栈是不是空,是空的话循环把Q1的全部数值,导入到Q2,
取出Q2栈顶给tab,Q2出栈,返回tab。
判断Q2栈是不是空,是空的话循环把Q1的全部数值,导入到Q2
返回Q2栈顶的元素就行了。
判断队列是不是空,是空返回false,不是空返回true。
把Q1和Q2的栈销毁,然后销毁obj,把obj置为空。
- typedef int data;
- typedef struct stack
- {
- data* arr;//存放数值
- int koj; //空间
- int top; //栈顶
- }stack;
-
-
- //初始化
- void stack_csh(SL* r)
- {
- assert(r);
- r->arr = NULL;
- r->koj = r->top = 0;
- }
-
-
- //入栈
- void stack_push(stack* r, data x)
- {
- assert(r);
- //空间大小等于栈顶,就说明空间不够
- if (r->koj == r->top)
- {
- int koj1 = r->koj == 0 ? 4 : 2 * r->koj;
- stack* tab = (stack*)realloc(r->arr, sizeof(stack));
- if (tab == NULL)
- {
- perror("realloc");
- exit(1);
- }
- //把新申请的空间给r
- r->arr = tab;
- r->koj = koj1;
- }
- //空间够直接入栈
- r->arr[r->top] = x;
- r->top++;
- }
-
- //布尔类型
- bool buer(stack* r)
- {
- assert(r);
- return r->top == 0;
- }
-
-
- //出栈
- void stack_pop(stack* r)
- {
- assert(r);
- //布尔类型
- assert(!buer(r));
- r->top--;
- }
-
-
- //取出栈顶
- data stack_top(stack* r)
- {
- assert(r);
- assert(!buer(r));
- return r->arr[r->top - 1];
- }
-
-
- //有效个数
- data stack_size(stack* r)
- {
- assert(r);
- return r->top;
- }
-
-
-
-
- //销毁
- void xiaoh(stack* r)
- {
- assert(r);
- if (r->arr != NULL)
- {
- free(r->arr);
- }
- r->arr = NULL;
- r->koj = r->top = 0;
- }
- //上面是栈的函数
-
-
- /
-
-
- //下面是实现代码
- typedef struct {
- //创建2个栈
- stack Q1;
- stack Q2;
- } MyQueue;
-
- //初始化
- MyQueue* myQueueCreate() {
- //创建指针指向Q1和Q2
- MyQueue* ps = (MyQueue*)malloc(sizeof(MyQueue));
- //初始化2个栈
- stack_csh(&ps->Q1);
- stack_csh(&ps->Q2);
- //返回ps
- return ps;
- }
-
-
-
- //入栈(入队列)
- void myQueuePush(MyQueue* obj, int x) {
- //调用入栈函数,为Q1入栈
- stack_push(&obj->Q1 , x);
- }
-
-
- //出栈(出队列,头)
- int myQueuePop(MyQueue* obj) {
- //判断Q2是不是空,不是空说明Q2栈里有数据
- if( buer(&obj->Q2) )
- {
- //是空,循环取出Q1的数值,导入Q2栈里
- while(!buer(&obj->Q1))
- {
- //入栈到Q2 取出Q1栈顶
- stack_push(&obj->Q2,stack_top(&obj->Q1));
- //Q1出栈
- stack_pop(&obj->Q1);
- }
- }
-
- //取出Q2的栈顶给tab(取队头)
- int tab = stack_top(&obj->Q2);
- //Q2出栈
- stack_pop(&obj->Q2);
- return tab;
- }
-
- //取栈顶(队头)
- int myQueuePeek(MyQueue* obj) {
- //判断Q2是不是空,不是空说明Q2栈里有数据
- if( buer(&obj->Q2) )
- {
- //是空,循环取出Q1的数值,导入Q2栈里
- while(!buer(&obj->Q1))
- {
- //入栈到Q2 取出Q1栈顶
- stack_push(&obj->Q2,stack_top(&obj->Q1));
- //Q1出栈
- stack_pop(&obj->Q1);
- }
- }
- //返回Q2的栈顶(返回队头)
- return stack_top(&obj->Q2);
- }
-
-
- bool myQueueEmpty(MyQueue* obj) {
- //判断这2个栈是不是都为空(判断队列是不是空)
- return buer(&obj->Q1) && buer(&obj->Q2);
- }
-
-
- void myQueueFree(MyQueue* obj) {
- //销毁
- xiaoh(&obj->Q1);
- xiaoh(&obj->Q2);
- //也把obj销毁
- free(obj);
- obj=NULL;
- }
-
-
- /**
- * Your MyQueue struct will be instantiated and called as such:
- * MyQueue* obj = myQueueCreate();
- * myQueuePush(obj, x);
-
- * int param_2 = myQueuePop(obj);
-
- * int param_3 = myQueuePeek(obj);
-
- * bool param_4 = myQueueEmpty(obj);
-
- * myQueueFree(obj);
- */
https://leetcode.cn/problems/design-circular-queue/description/
这个队列底层使用数组,比较好实现。
结构体的参数,数组,头,尾,空间大小。
申请ps的一个结构体,
给arr申请一个数值的空间,我们申请的数值空间必须多一块空间,方便5%5等于0。
初始化:把头尾初始化为0,空间大小初始化为k,k就是4。
第一步:先判断队列是不是满了,满了直接返回false,没有满插入数据。
第二步:为arr数组wei下标位置插入数据,然后++,参考【1%5=1, 2%5=2 ,3%5=3, 4%5=4, 5%5=0】。
当wei走到下标为5,5%5=0,所以就会回到0,返回true。
第一步:判断队列是不是空,是空直接返回false。
第二步:头直接++就好了,1%5=1, 2%5=2 ,3%5=3, 4%5=4, 5%5=0
当to走到下标为5,5%5=0,所以就会回到0,返回true。
先判断是不是空,不是空返回头,是空返回-1。
第一步:判断队列是不是空。
第二步:把wei-1的数据赋值tab,为什么是wei-1呢?
上面这一张图,我们可以看到插入数据后就++了,所以我们取队尾,wei-1。
第三步:判断尾下标是不是0,这里是一种特殊情况0-1=-1,-1没有下标,
我们直接把空间大小给tab就是下标为4这个元素了。
返回arr下标为tab的数值。
- typedef struct {
- int *arr;
- int to;//头
- int wei;//尾
- int kojdax;//空间大小
- } MyCircularQueue;
-
- //初始化
- MyCircularQueue* myCircularQueueCreate(int k) {
- //申请空间
- MyCircularQueue* ps = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
- // 4 * 5 = 20,就是5个空间
- ps->arr = (int*)malloc(sizeof(int) * (k + 1));
- //初始化
- ps->to = ps->wei = 0;
- ps->kojdax = k;
- return ps;
- }
-
- bool myCircularQueueIsFull(MyCircularQueue* obj) {
- //判断队列是不是满了,等于头就说明满了
- return (obj->wei+1) % (obj->kojdax+1) == obj->to;
- }
-
-
- //入队列
- bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
- //队列满了不能插入数据
- if(myCircularQueueIsFull(obj))
- {
- return false;
- }
-
- //在wei位置插入数据,然后++
- obj->arr[obj->wei++] = value;
- //5 % 5 = 0,rear走到5下标的时候回到下标为0的位置。
- obj->wei %= obj->kojdax + 1;
- return true;
-
- }
-
- bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
- //等于就说明队列是空
- return obj->to == obj->wei;
- }
-
- //出队列
- bool myCircularQueueDeQueue(MyCircularQueue* obj) {
- //队列为空
- if(myCircularQueueIsEmpty(obj))
- {
- return false;
- }
- //队列不为空
-
- //头往后走就行
- obj->to++;
- //会越界所以:5 % 5 = 0,to走到5下标的时候回到下标为0的位置。
- obj->to %= obj->kojdax + 1;
- return true;
- }
-
-
- //取队头
- int myCircularQueueFront(MyCircularQueue* obj) {
- //判断队列是不是空
- if(myCircularQueueIsEmpty(obj))
- {
- return -1;
- }
- //返回头
- return obj->arr[obj->to];
-
- }
-
-
- //取队尾
- int myCircularQueueRear(MyCircularQueue* obj) {
-
- //判断队列是不是空
- if(myCircularQueueIsEmpty(obj))
- {
- return -1;
- }
-
- //把wei-1的数据给tab
- int tab = obj->wei - 1;
- //尾等于下标0
- if(obj->wei == 0)
- {
- //把有效个数4给tab
- tab = obj -> kojdax;
- }
- //返回tab
- return obj->arr[tab];
- }
-
-
-
- //销毁
- void myCircularQueueFree(MyCircularQueue* obj) {
- free(obj->arr);
- free(obj);
- obj=NULL;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。