首页 > 编程语言 >代码随想录算法训练营第十天|Day10栈与队列

代码随想录算法训练营第十天|Day10栈与队列

时间:2024-10-12 20:20:42浏览次数:9  
标签:obj 第十天 int 随想录 queue 队列 Day10 return stack

232.用栈实现队列

题目链接/文章讲解/视频讲解:https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.html

思路

这是一道模拟题,不涉及到具体算法,使用栈来模拟队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈。

#define MAX_SIZE 1000   
typedef struct {  
    int top;  
    int data[MAX_SIZE];  
} Stack;  
void initStack(Stack *stack) {  
    stack->top = -1;  
}   
bool isEmpty(Stack *stack) {  
    return stack->top == -1;  
}   
void push(Stack *stack, int value) {  
    if (stack->top < MAX_SIZE - 1) {  
        stack->data[++stack->top] = value;  
    } else {  
        printf("Stack overflow\n");  
    }  
}   
int pop(Stack *stack) {  
    if (!isEmpty(stack)) {  
        return stack->data[stack->top--];  
    } else {  
        printf("Stack underflow\n");  
        return -1;  
    }  
}  
int peek(Stack *stack) {  
    if (!isEmpty(stack)) {  
        return stack->data[stack->top];  
    } else {  
        printf("Stack is empty\n");  
        return -1;  
    }  
}  
  
typedef struct {  
    Stack inputStack;  
    Stack outputStack;  
} MyQueue;  
MyQueue* myQueueCreate() {  
    MyQueue *obj = (MyQueue*)malloc(sizeof(MyQueue));  
    initStack(&obj->inputStack);  
    initStack(&obj->outputStack);  
    return obj;  
}  
void myQueuePush(MyQueue* obj, int x) {  
    push(&obj->inputStack, x);  
}  
void moveElements(Stack *inputStack, Stack *outputStack) {  
    while (!isEmpty(inputStack)) {  
        push(outputStack, pop(inputStack));  
    }  
}    
int myQueuePop(MyQueue* obj) {  
    if (isEmpty(&obj->outputStack)) {  
        moveElements(&obj->inputStack, &obj->outputStack);  
    }  
    return pop(&obj->outputStack);  
}  
int myQueuePeek(MyQueue* obj) {  
    if (isEmpty(&obj->outputStack)) {  
        moveElements(&obj->inputStack, &obj->outputStack);  
    }  
    return peek(&obj->outputStack);  
}   
bool myQueueEmpty(MyQueue* obj) {  
    return isEmpty(&obj->inputStack) && isEmpty(&obj->outputStack);  
}  
void myQueueFree(MyQueue* obj) {  
    free(obj);  
}  

学习反思

栈和队列的原理:队列是先进先出,栈是先进后出。

225. 用队列实现栈

题目链接/文章讲解/视频讲解:https://programmercarl.com/0225.%E7%94%A8%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.html

思路

typedef struct {
    int* data;
    int front;
    int back;
    int size;
    int capacity;
} Queue;
Queue* createQueue(int capacity) {
    Queue* queue = (Queue*)malloc(sizeof(Queue));
    queue->data = (int*)malloc(sizeof(int) * capacity);
    queue->front = 0;
    queue->back = 0;
    queue->size = 0;
    queue->capacity = capacity;
    return queue;
}
void enqueue(Queue* queue, int value) {
    queue->data[queue->back] = value;
    queue->back = (queue->back + 1) % queue->capacity;
    queue->size++;
}
int dequeue(Queue* queue) {
    int value = queue->data[queue->front];
    queue->front = (queue->front + 1) % queue->capacity;
    queue->size--;
    return value;
}
int peek(Queue* queue) {
    return queue->data[queue->front];
}
bool isEmpty(Queue* queue) {
    return queue->size == 0;
}
void freeQueue(Queue* queue) {
    free(queue->data);
    free(queue);
}
typedef struct {
    Queue* queue1;
    Queue* queue2;
} MyStack;
MyStack* myStackCreate() {
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
    obj->queue1 = createQueue(100); // 初始化队列,容量设定为 100
    obj->queue2 = createQueue(100);
    return obj;
}
void myStackPush(MyStack* obj, int x) {
    enqueue(obj->queue2, x);
    while (!isEmpty(obj->queue1)) {
        enqueue(obj->queue2, dequeue(obj->queue1));
    }
    Queue* temp = obj->queue1;
    obj->queue1 = obj->queue2;
    obj->queue2 = temp;
}
int myStackPop(MyStack* obj) {
    return dequeue(obj->queue1);
}
int myStackTop(MyStack* obj) {
    return peek(obj->queue1);
}
bool myStackEmpty(MyStack* obj) {
    return isEmpty(obj->queue1);
}
void myStackFree(MyStack* obj) {
    freeQueue(obj->queue1);
    freeQueue(obj->queue2);
    free(obj);
}

学习反思

队列模拟栈,其实一个队列就够了,那么我们先说一说两个队列来实现栈的思路。队列是先进先出的规则,把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并没有变成先进后出的顺序。所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。但是依然还是要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用来备份的!用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。

20. 有效的括号

题目链接/文章讲解/视频讲解:https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html

思路

int notMatch(char par, char* stack, int stackTop) {
    switch(par) {
        case ']':
            return stack[stackTop - 1] != '[';
        case ')':
            return stack[stackTop - 1] != '(';
        case '}':
            return stack[stackTop - 1] != '{';
    }
    return 0;
}
bool isValid(char * s){
    int strLen = strlen(s);
    char stack[5000];
    int stackTop = 0;
    int i;
    for(i = 0; i < strLen; i++) {
        char tempChar = s[i];
        if(tempChar == '(' || tempChar == '[' || tempChar == '{')
            stack[stackTop++] = tempChar;
        else if(stackTop == 0 || notMatch(tempChar, stack, stackTop))
            return 0;
        else
            stackTop--;
    }
    return !stackTop;
}

学习反思

由于栈结构的特殊性,非常适合做对称匹配类的题目。

首先要弄清楚,字符串里的括号不匹配有几种情况。

一些同学,在面试中看到这种题目上来就开始写代码,然后就越写越乱。

建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。

先来分析一下 这里有三种不匹配的情况,

  1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。

  2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。 

  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配

我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。

第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

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

题目链接/文章讲解/视频讲解:https://programmercarl.com/1047.%E5%88%A0%E9%99%A4%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E7%9B%B8%E9%82%BB%E9%87%8D%E5%A4%8D%E9%A1%B9.html

思路

char* removeDuplicates(char* s) {
    int len = strlen(s);
    char* stack = (char*)malloc((len + 1) * sizeof(char)); 
    int stackSize = 0;
    for (int i = 0; i < len; i++) {
        if (stackSize > 0 && stack[stackSize - 1] == s[i]) {
            stackSize--;
        } else {
            stack[stackSize] = s[i];
            stackSize++;
        }
    }
    stack[stackSize] = '\0'; 
    char* result = (char*)malloc((stackSize + 1) * sizeof(char)); 
    strcpy(result, stack); 
    free(stack);
    return result; 
}

学习反思

这个函数通过动态内存分配来创建一个临时的栈,并在处理完字符串后,将其内容复制到一个新的字符串中,然后返回这个新字符串。

总结

了解了队列和栈,加油!!!

 

标签:obj,第十天,int,随想录,queue,队列,Day10,return,stack
From: https://blog.csdn.net/a6666999d/article/details/142791316

相关文章

  • 代码随想录算法训练营第十二天|Day12二叉树
    递归遍历 题目链接/文章讲解/视频讲解:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E9%80%92%E5%BD%92%E9%81%8D%E5%8E%86.html思路每次写递归,按照三要素来写,可以写出正确的递归算法!确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要......
  • 代码随想录算法训练营第十一天|Day11栈与队列
    150.逆波兰表达式求值题目链接/文章讲解/视频讲解:https://programmercarl.com/0150.%E9%80%86%E6%B3%A2%E5%85%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BC.html思路#defineMAX_TOKENS1000#defineMAX_TOKEN_LEN10typedefstruct{longlongdat......
  • 代码随想录算法训练营第十三天|Day13二叉树
    226.翻转二叉树题目链接/文章讲解/视频讲解:https://programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html思路只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果递归法structTreeNode*invertTree(structTreeNode*root){if(!......
  • 代码随想录训练营第五天|Leetcode.349,Leetcode.454,Leetcode19,Leetcode18
    一、哈希表和set和map和数组的关系 用哈希表,判断是否出现过。数值很大或者数值很分散时,不用数组,占用空间大,用set。set,multiset数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判......
  • 代码随想录训练营第60天|冗余连接
    108.冗余连接#include<iostream>#include<vector>usingnamespacestd;intn;//节点数量vector<int>father(1001,0);//按照节点大小范围定义数组//并查集初始化voidinit(){for(inti=0;i<=n;++i){father[i]=i;}}//并查集......
  • 代码随想录算法训练营day12|144.二叉树的前序遍历 94.二叉树的中序遍历 145.二叉
    学习资料:https://programmercarl.com/二叉树理论基础.html二叉树:满二叉树、完全二叉树、二叉搜索数、平衡二叉搜索树;链式存储、顺序存储;前序/中序/后序遍历递归法、迭代法,层序深度优先搜索dfs,广度优先搜索学习记录:144.二叉树的前序遍历(也要注重二叉数的输入方式;递归法比迭......
  • 代码随想录Day23 | LeetCode 455. 分发饼干、LeetCode 53. 最大子数组和、LeetCode 37
    LeetCode455.分发饼干贪心就是干classSolution:deffindContentChildren(self,g:List[int],s:List[int])->int:g.sort(reverse=True)s.sort(reverse=True)i=j=0res=0whilei<len(g)andj<len(......
  • 代码随想录算法训练营 | 完全背包,518. 零钱兑换 II,377. 组合总和 Ⅳ,70. 爬楼梯 (进阶)
    完全背包题目链接:完全背包文档讲解︰代码随想录(programmercarl.com)视频讲解︰完全背包日期:2024-10-11想法:dp数组设置思路跟01背包一样,不同在遍历上,完全背包遍历背包大小是从weight[i]开始的(背包空间小于weight[i]就没有意义,不用考虑,直接用之前的对应数值就行了),从前往后遍历就能......
  • 01数组算法/代码随想录
    一、数组好久没写算法题,之前喜欢按着习惯选择刷题,很早以前就听说代码随想录,今天跟着代码随想录再过一遍算法1.1二分查找常见疑问middle一定是在[left,right]这个范围内标准代码不会越界,因为在elseif中出现越界后,下一次循环就不会通过左闭右闭区间代码示例public......
  • 代码随想录算法训练营 | 1049. 最后一块石头的重量 II,494. 目标和,474.一和零
    1049.最后一块石头的重量II题目链接:1049.最后一块石头的重量II文档讲解︰代码随想录(programmercarl.com)视频讲解︰最后一块石头的重量II日期:2024-10-10想法:这这么会是分割等和子集一类的问题。。。Java代码如下:classSolution{publicintlastStoneWeightII(int[]......