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

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

时间:2024-10-12 20:20:01浏览次数:3  
标签:第十一天 int 随想录 long st queue ++ Day11 result

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

思路

#define MAX_TOKENS 1000  
#define MAX_TOKEN_LEN 10    
typedef struct {  
    long long data[MAX_TOKENS];  
    int top;  
} Stack;   
void initStack(Stack *st) {  
    st->top = -1;  
}   
bool isStackEmpty(Stack *st) {  
    return st->top == -1;  
}   
bool isStackFull(Stack *st) {  
    return st->top == MAX_TOKENS - 1;  
}   
void push(Stack *st, long long value) {  
    if (!isStackFull(st)) {  
        st->data[++st->top] = value;  
    } else {  
        printf("Stack overflow\n");  
        exit(EXIT_FAILURE);  
    }  
}    
long long pop(Stack *st) {  
    if (!isStackEmpty(st)) {  
        return st->data[st->top--];  
    } else {  
        printf("Stack underflow\n");  
        exit(EXIT_FAILURE);  
    }  
}    
long long evalRPN(char *tokens[], int tokensSize) {  
    Stack st;  
    initStack(&st);   
    for (int i = 0; i < tokensSize; i++) {  
        if (strcmp(tokens[i], "+") == 0 || strcmp(tokens[i], "-") == 0 ||  
            strcmp(tokens[i], "*") == 0 || strcmp(tokens[i], "/") == 0) {  
            long long num1 = pop(&st);  
            long long num2 = pop(&st);  
            long long result;  
            if (strcmp(tokens[i], "+") == 0) result = num2 + num1;  
            else if (strcmp(tokens[i], "-") == 0) result = num2 - num1;  
            else if (strcmp(tokens[i], "*") == 0) result = num2 * num1;  
            else if (strcmp(tokens[i], "/") == 0) {   
                if (num1 == 0) {  
                    printf("Division by zero\n");  
                    exit(EXIT_FAILURE);  
                }  
                result = num2 / num1;  
            }  
            push(&st, result);  
        } else {  
            char *endptr;  
            long long num = strtoll(tokens[i], &endptr, 10);  
            if (*endptr != '\0') {  
                printf("Invalid number: %s\n", tokens[i]);  
                exit(EXIT_FAILURE);  
            }  
            push(&st, num);  
        }  
    }   
    long long result = pop(&st);  
    return result;  
}  

学习反思

栈与递归之间在某种程度上是可以转换的。

239. 滑动窗口最大值

题目链接/文章讲解/视频讲解:https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html

思路

#define MAX_SIZE 100000 
typedef struct {  
    int *data; 
    int front; 
    int rear;    
    int size;    
    int capacity; 
} MyQueue;  
void initQueue(MyQueue *queue, int capacity) {  
    queue->data = (int *)malloc(capacity * sizeof(int));  
    queue->front = 0;  
    queue->rear = -1;  
    queue->size = 0;  
    queue->capacity = capacity;  
}   
void destroyQueue(MyQueue *queue) {  
    free(queue->data);  
    queue->data = NULL;  
    queue->front = queue->rear = queue->size = queue->capacity = 0;  
}  
int isEmpty(MyQueue *queue) {  
    return queue->size == 0;  
}    
void pop(MyQueue *queue, int value) {  
    if (!isEmpty(queue) && queue->data[queue->front] == value) {  
        queue->front++;  
        queue->size--;  
    }  
}   
void push(MyQueue *queue, int value) {  
    while (!isEmpty(queue) && value > queue->data[queue->rear]) {  
        queue->rear--;  
        queue->size--;  
    }  
    queue->rear++;  
    if (queue->rear >= queue->capacity) {  
        queue->rear = 0; 
    }  
    queue->data[queue->rear] = value;  
    queue->size++;  
} 
int front(MyQueue *queue) {  
    return queue->data[queue->front];  
}   
void adjustQueue(MyQueue *queue) {  
    if (queue->rear >= queue->capacity - 1) {  
        int newFront = queue->rear + 1;  
        if (newFront >= queue->capacity) {  
            newFront = 0;  
        }  
        for (int i = queue->rear; i >= queue->front; i--) {  
            int idx = (i + 1) % queue->capacity;  
            if (idx == newFront) {  
                break;  
            }  
            queue->data[idx] = queue->data[i];  
        }  
        queue->front = newFront;  
        queue->rear = newFront - 1;  
        queue->size = 0;  
    }  
}  
int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) {  
    MyQueue queue;  
    initQueue(&queue, numsSize);   
    int *result = (int *)malloc((numsSize - k + 1) * sizeof(int));  
    *returnSize = 0;  
    for (int i = 0; i < k; i++) {  
        push(&queue, nums[i]);  
    }  
    result[(*returnSize)++] = front(&queue);  
    for (int i = k; i < numsSize; i++) {  
        pop(&queue, nums[i - k]);  
        push(&queue, nums[i]);  
        result[(*returnSize)++] = front(&queue);  
    }    
    destroyQueue(&queue); 
    return result;  
}  

学习反思

想用一个大顶堆(优先级队列)来存放这个窗口里的k个数字,这样就可以知道最大的最大值是多少了,问题是这个窗口是移动的,而大顶堆每次只能弹出最大值,我们无法移除其他数值,这样就造成大顶堆维护的不是滑动窗口里面的数值了。所以不能用大顶堆。此时我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。

347.前 K 个高频元素

题目链接/文章讲解/视频讲解:https://programmercarl.com/0347.%E5%89%8DK%E4%B8%AA%E9%AB%98%E9%A2%91%E5%85%83%E7%B4%A0.html

思路

typedef struct {
    int num;   
    int count;  
} Element;

int compare(const void *a, const void *b) {
    return ((Element *)a)->count - ((Element *)b)->count;
}

int* topKFrequent(int* nums, int numsSize, int k, int* returnSize) {
    int freq[10001] = {0}; 
    for (int i = 0; i < numsSize; i++) {
        freq[nums[i]]++;
    }
    Element *heap = (Element *)malloc(k * sizeof(Element));
    int heapSize = 0;
    for (int i = 0; i < 10001; i++) {
        if (freq[i] == 0) {
            continue; 
        }
        if (heapSize < k) {
            heap[heapSize].num = i;
            heap[heapSize].count = freq[i];
            heapSize++;
            qsort(heap, heapSize, sizeof(Element), compare);
        } else if (freq[i] > heap[0].count) { 
            heap[0].num = i;
            heap[0].count = freq[i];
            qsort(heap, heapSize, sizeof(Element), compare);
        }
    }
    int *result = (int *)malloc(k * sizeof(int));
    for (int i = 0; i < k; i++) {
        result[i] = heap[i].num;
    }
    free(heap);
    *returnSize = k;
    return result;
}

学习反思

有点难度。

总结

加油!!!

标签:第十一天,int,随想录,long,st,queue,++,Day11,result
From: https://blog.csdn.net/a6666999d/article/details/142828161

相关文章

  • 代码随想录算法训练营第十三天|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[]......
  • 代码随想录算法训练营day11|150. 逆波兰表达式求值 239. 滑动窗口最大值 347.前 K
    学习资料:https://programmercarl.com/0150.逆波兰表达式求值.html#算法公开课栈、队列、堆学习记录:150.逆波兰表达式求值(中序表达式转换为后序表达式,用栈实现;遇到符号就从栈中取前两个元素进行运算,再放回去)点击查看代码fromoperatorimportadd,sub,muldefdiv(x,y):......
  • 代码随想录算法训练营 | 背包问题 二维,背包问题 一维,416. 分割等和子集
    背包问题二维题目链接:背包问题二维文档讲解︰代码随想录(programmercarl.com)视频讲解︰背包问题二维日期:2024-10-09想法:dp[i][j],i表示需要从物品0-i中选择加入到背包中,j表示背包的容量,dp值表示最大的价值;递推公式,如果背包大小j都比此时要放的物品i的weight[i]小了,背包放不下......