代码随想录第10天打卡·leetcode·栈和队列1:232.用栈实现队列;225. 用队列实现栈;1047. 删除字符串中的所有相邻重复项;20. 有效的括号

232.用栈实现队列

力扣题目链接(opens new window)

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。

思路:

1、push:直接放入栈1

2、pop:(考虑到栈2中的元素是先进入的,永远比栈1先输出)

        情况1:栈2是空的,则把栈1元素输出至栈2(自然逆向)

        情况2:栈2还有未输出的元素

        ——输出栈2的第一个元素

3、peek:可以基于pop算法,但是并不需要pop掉,故而再放回(不要直接复制)

4、empty:两个链表都空,表明队列空

**注意:

create:

- create的过程中是需要开辟空间的!!

-对于栈和队列的情况,create的时候 为top /front rear指针赋值 

-对于创建create函数可以这样写:返回mystack的指针

MyStack* myStackCreate() {
    MyStack *s=(MyStack *)malloc(sizeof(MyStack));
    s->front=s->rear=-1;
    return s;
}

typedef struct: 

注意给data [MAXSIZE],有时候会忘记写 [MAXSIZE]

i++ & ++i :

单独情况:++i和i++,效果都是i=i+1。

实际上:i++是先赋值,然后再自增;++i是先自增,后赋值(++在前,先自增)。

代码:

typedef struct {
    int data1[500],data2[500];
    int top1,top2;
} MyQueue;

MyQueue* myQueueCreate() {
    MyQueue *l=(MyQueue *)malloc(sizeof(MyQueue));
    l->top1=-1;
    l->top2=-1;
    return l;
}

void myQueuePush(MyQueue* obj, int x) {
    obj->top1++;
    obj->data1[obj->top1]=x;
}

int myQueuePop(MyQueue* obj) {
    int answer;
    if(obj->top2==-1){//如果出栈空了的话,把新进入的 逆序放入
        while(obj->top1>=0){
            obj->top2++;
            obj->data2[obj->top2]=obj->data1[obj->top1];
            obj->top1--;
        }
    }
    answer=obj->data2[obj->top2];
    obj->top2--;
    return answer;
}

int myQueuePeek(MyQueue* obj) {
    int answer=  myQueuePop(obj);
    obj->top2++;
    obj->data2[obj->top2]=answer;
    return answer;
}

bool myQueueEmpty(MyQueue* obj) {
    if(obj->top1==-1 && obj->top2==-1) return true;
    return false;
}

void myQueueFree(MyQueue* obj) {
    obj->top1=-1;
    obj->top2=-1;
}

225. 用队列实现栈

力扣题目链接(opens new window)

使用队列实现栈的下列操作:

  • push(x) -- 元素 x 入栈
  • pop() -- 移除栈顶元素
  • top() -- 获取栈顶元素
  • empty() -- 返回栈是否为空

注意:

  • 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

思路:

**后续可以尝试只用一个队列实现

代码:

typedef struct {
    int front1,rear1,front2,rear2;
    int data1[5000],data2[5000];
} MyStack;


MyStack* myStackCreate() {
    MyStack *s=(MyStack *)malloc(sizeof(MyStack));
    s->front1=s->rear1=s->front2=s->rear2=-1;
    return s;
}

void myStackPush(MyStack* obj, int x) {
    obj->data1[++obj->rear1]=x;
}

int myStackPop(MyStack* obj) {
    int answer;

    while(obj->front1!=obj->rear1-1){//除了队列1最后一个元素,其他复制到2去
        obj->data2[++obj->rear2]=obj->data1[++obj->front1];
    }

    answer=obj->data1[++obj->front1];//读取1中剩余元素,并弹出

    while(obj->front2!=obj->rear2){//2全部复制回1
        obj->data1[++obj->rear1]=obj->data2[++obj->front2];
    }
    return answer;
}

int myStackTop(MyStack* obj) {
    int answer=myStackPop(obj);
    myStackPush(obj,answer);
    return answer;
}

bool myStackEmpty(MyStack* obj) {
    if(obj->front1==obj->rear1 && obj->front2==obj->rear2) return true;
    return false;
}

void myStackFree(MyStack* obj) {
    obj->front1=obj->rear1=obj->front2=obj->rear2=-1;
}

1047. 删除字符串中的所有相邻重复项

力扣题目链接(opens new window)

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

  • 输入:"abbaca"
  • 输出:"ca"
  • 解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

提示:

  • 1 <= S.length <= 20000
  • S 仅由小写英文字母组成。

**注意:

**注意在字符串操作时:改变长度后,需要补上‘\0’的位置

**判断使用栈还是队列:先入先出,后入先出;出数据 和 进入数据是否为同一端

typedef struct {
    char data[99999];
    int top;
}listnode;

void push(listnode * l,char e){
    l->top++;
    l->data[l->top]=e;
}

void pop(listnode *l){
    l->top--;
}

char get(listnode *l){
    return l->data[l->top];
}

bool empty(listnode*l){
    if(l->top==-1) return true;
    return false;
}

char* removeDuplicates(char* s) {
    listnode *l=(listnode *)malloc(sizeof(listnode));
    l->top=-1;

    for(int i=0;i<strlen(s);i++){//遍历每个字母
        if(empty(l)) push(l,s[i]); //链表空了则进栈
        else if(get(l)!=s[i]) push(l,s[i]);//与上一位不同,进栈
        else pop(l);//与上一位相同,上一位出栈,这一位也不能进栈
    } 
    
    int i=0;

    while(!empty(l)){//出栈,写入s
        s[i]=get(l);
        pop(l);
        i++;
    }
    s[i]='\0';//字符串结束了
    i=0;
    
    int j=strlen(s)-1;//出栈顺序 和 要求的顺序相反,故而再转换一下
    while(i<j){
        char tem=s[i];
        s[i]=s[j];
        s[j]=tem;
        i++;
        j--;
    }

    return s;
}

优化:

看了代码随想录后发现有可以优化:直接返回栈作为字符串 :用字符串当作栈,最后直接return stack即可

char* stack = (char*)malloc(sizeof(char) * strLength + 1);
    int stackTop = 0;

也可以用双指针的方法解决

20. 有效的括号

使用栈

**输入左括号,进栈右括号——简化对输入右括号情况的讨论

typedef struct node{
    char data[11000];
    int top;
}listnode;

void push(listnode *l,char e){
    l->top++;
    l->data[l->top]=e;
}

char pop(listnode *l){
    char e;
    e=l->data[l->top];
    l->top--;
    return e;
}

bool empty(listnode*l){
    if(l->top==-1) return true;
    return false;
}

bool isValid(char* s) {
    listnode *l=(listnode*)malloc(sizeof(listnode));
    l->top=-1;
    
    for(int i=0;i<strlen(s);i++){
        if(s[i]=='(')  push(l,')');
        else if (s[i]=='{')  push(l,'}');
        else if (s[i]=='[')  push(l,']');
        else {
            if(empty(l) || pop(l)!=s[i]) return false;
        }
       
    }
    if(empty(l)) return true;
    else return false;
}

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值