栈和列队(LeetCode)

个人主页流年如梦

专栏《C语言》 《数据结构》

文章目录

一.有效的括号

点击转跳👈

原题

🧐思路:遇到左括号就入栈,遇到右括号就和栈顶的左括号匹配,不匹配或栈空则无效,遍历结束后栈空才说明所有括号都匹配

参考代码如下

c 复制代码
bool isValid(char* s) {
    char stack[1000];
    int top = -1;
    for (int i = 0; s[i]; i++) {
        if (s[i] == '(' || s[i] == '[' || s[i] == '{') 
        {
            stack[++top] = s[i];
        } 
        else 
        {
            if (top == -1) return false;
            char topChar = stack[top--];
            if ((s[i] == ')' && topChar != '(') ||
                (s[i] == ']' && topChar != '[') ||
                (s[i] == '}' && topChar != '{')) 
            {
                return false;
            }
        }
    }
    return top == -1;
}

二.用队列实现栈

点击转跳👈

原题

🧐思路 :用两个队列模拟栈;用一个队列存元素,每次 push时直接入队;poptop时,把主队列除最后一个元素外,全部转移到辅助队列,这样主队列剩下的元素就是栈顶元素,操作完再把元素移回主队列

参考代码如下

c 复制代码
typedef struct {
    int* data;
    int front;
    int rear;
    int size;
} Queue;

Queue* queueCreate(int maxSize) {
    Queue* q = (Queue*)malloc(sizeof(Queue));
    q->data = (int*)malloc(sizeof(int) * maxSize);
    q->front = 0;
    q->rear = 0;
    q->size = maxSize;
    return q;
}

bool queuePush(Queue* q, int x) {
    if ((q->rear + 1) % q->size == q->front) return false;
    q->data[q->rear] = x;
    q->rear = (q->rear + 1) % q->size;
    return true;
}

int queuePop(Queue* q) {
    if (q->front == q->rear) return -1;
    int val = q->data[q->front];
    q->front = (q->front + 1) % q->size;
    return val;
}

bool queueEmpty(Queue* q) {
    return q->front == q->rear;
}

typedef struct {
    Queue* q1;
    Queue* q2;
} MyStack;

MyStack* myStackCreate() {
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
    obj->q1 = queueCreate(100);
    obj->q2 = queueCreate(100);
    return obj;
}

void myStackPush(MyStack* obj, int x) {
    queuePush(obj->q1, x);
}

int myStackPop(MyStack* obj) {
    while (obj->q1->rear - obj->q1->front > 1) {
        queuePush(obj->q2, queuePop(obj->q1));
    }
    int val = queuePop(obj->q1);
    Queue* temp = obj->q1;
    obj->q1 = obj->q2;
    obj->q2 = temp;
    return val;
}

int myStackTop(MyStack* obj) {
    while (obj->q1->rear - obj->q1->front > 1) {
        queuePush(obj->q2, queuePop(obj->q1));
    }
    int val = obj->q1->data[obj->q1->front];
    queuePush(obj->q2, queuePop(obj->q1));
    Queue* temp = obj->q1;
    obj->q1 = obj->q2;
    obj->q2 = temp;
    return val;
}

bool myStackEmpty(MyStack* obj) {
    return queueEmpty(obj->q1);
}

三.用栈实现队列

点击转跳👈

原题

🧐思路 :要用两个栈模拟队列;用一个栈inStack负责 push操作,另一个栈outStack负责poppeek操作;当需要poppeek时,如果outStack为空,就把inStack里的所有元素依次弹出并压入outStack,这样outStack的栈顶就是队列的队头元素

参考代码如下

c 复制代码
typedef struct {
    int* data;
    int top;
    int size;
} Stack;

Stack* stackCreate(int maxSize) {
    Stack* s = (Stack*)malloc(sizeof(Stack));
    s->data = (int*)malloc(sizeof(int) * maxSize);
    s->top = -1;
    s->size = maxSize;
    return s;
}

void stackPush(Stack* s, int x) {
    s->data[++s->top] = x;
}

int stackPop(Stack* s) {
    return s->data[s->top--];
}

int stackPeek(Stack* s) {
    return s->data[s->top];
}

bool stackEmpty(Stack* s) {
    return s->top == -1;
}

typedef struct {
    Stack* inStack;
    Stack* outStack;
} MyQueue;

MyQueue* myQueueCreate() {
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    obj->inStack = stackCreate(100);
    obj->outStack = stackCreate(100);
    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    stackPush(obj->inStack, x);
}

void transfer(MyQueue* obj) {
    while (!stackEmpty(obj->inStack)) {
        stackPush(obj->outStack, stackPop(obj->inStack));
    }
}

int myQueuePop(MyQueue* obj) {
    if (stackEmpty(obj->outStack)) {
        transfer(obj);
    }
    return stackPop(obj->outStack);
}

int myQueuePeek(MyQueue* obj) {
    if (stackEmpty(obj->outStack)) {
        transfer(obj);
    }
    return stackPeek(obj->outStack);
}

bool myQueueEmpty(MyQueue* obj) {
    return stackEmpty(obj->inStack) && stackEmpty(obj->outStack);
}

四.设计循环队列

点击转跳👈

原题:

🧐思路

要求实现一个循环队列,核心是用数组+两个指针(队头front、队尾rear)实现,关键是牺牲一个位置来区分队空和队满

  1. 队列长度设为k+1(多一个位置作为标记)
  2. 队空条件:front == rear
  3. 队满条件:(rear + 1) % capacity == front

参考代码如下

c 复制代码
typedef struct {
    int* data;
    int front;
    int rear;
    int capacity;
} MyCircularQueue;

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->capacity = k + 1;
    obj->data = (int*)malloc(sizeof(int) * obj->capacity);
    obj->front = 0;
    obj->rear = 0;
    return obj;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if ((obj->rear + 1) % obj->capacity == obj->front) {
        return false;
    }
    obj->data[obj->rear] = value;
    obj->rear = (obj->rear + 1) % obj->capacity;
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if (obj->front == obj->rear) {
        return false;
    }
    obj->front = (obj->front + 1) % obj->capacity;
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if (obj->front == obj->rear) {
        return -1;
    }
    return obj->data[obj->front];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if (obj->front == obj->rear) {
        return -1;
    }
    return obj->data[(obj->rear - 1 + obj->capacity) % obj->capacity];
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front == obj->rear;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear + 1) % obj->capacity == obj->front;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->data);
    free(obj);
}

👀 关注 我们一路同行,从入门到大师,慢慢沉淀、稳步成长
❤️ 点赞 鼓励原创,让优质内容被更多人看见
⭐ 收藏 收好核心知识点与实战技巧,需要时随时查阅
💬 评论 分享你的疑问或踩坑经历,一起交流避坑、共同进步

相关推荐
Hello.Reader2 小时前
算法基础(十)——分治思想把大问题拆成小问题
java·开发语言·算法
逻辑驱动的ken3 小时前
Java高频考点场景题24
java·开发语言·面试·职场和发展·求职招聘
绛橘色的日落(。・∀・)ノ3 小时前
机器学习之评估与偏差方差分析
算法
消失的旧时光-19433 小时前
C语言对象模型系列(四)《Linux 内核里的 container_of 到底是什么黑魔法?》—— 一篇讲透 Linux 内核的“对象模型”核心技巧
linux·c语言·算法
AI_Ming4 小时前
从0开始学AI:层归一化,原来是这回事!
算法·ai编程
WL_Aurora4 小时前
备战蓝桥杯国赛【Day 8】
算法·蓝桥杯
智者知已应修善业4 小时前
【51单片机模拟生日蜡烛】2023-10-10
c++·经验分享·笔记·算法·51单片机
MediaTea4 小时前
Scikit-learn:从数据到结构——无监督学习的最小闭环
人工智能·学习·算法·机器学习·scikit-learn
智者知已应修善业4 小时前
【51单片机如何让LED灯从一亮到八,再从八亮到一】2023-10-13
c++·经验分享·笔记·算法·51单片机