【C++】每日一题 219 最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。

C++实现:

#include <stack>

class MinStack {
private:
    std::stack<int> mainStack;
    std::stack<int> minStack;

public:
    MinStack() {
        
    }

    void push(int val) {
        mainStack.push(val);
        if (minStack.empty() || val <= getMin()) {
            minStack.push(val);
        }
    }

    void pop() {
        if (mainStack.top() == getMin()) {
            minStack.pop();
        }
        mainStack.pop();
    }

    int top() {
        return mainStack.top();
    }

    int getMin() {
        return minStack.top();
    }
};

在这个实现中,我们使用了两个栈:mainStack 用于存储元素,minStack 用于存储当前栈中的最小元素。

在 push 操作中,我们将元素推入 mainStack 中,并且判断该元素是否比当前最小元素小或等于最小元素,如果是,则将该元素也推入 minStack 中。
在 pop 操作中,我们先判断要删除的元素是否为当前最小元素,如果是,则同时从 mainStack 和 minStack 中删除该元素。
top 操作直接返回 mainStack 的栈顶元素。
getMin 操作直接返回 minStack 的栈顶元素,即当前栈中的最小元素。
这样,通过维护一个辅助栈来保存当前栈中的最小元素,我们可以在常数时间内检索到最小元素,同时支持常见的栈操作。

因为C++有stack数据结构,所以相对C语言逻辑较易实现,这里也给出C语言的两种实现

  1. 链表实现
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int val;
    int minVal;
    struct Node* next;
} Node;

typedef struct {
    Node* top;
} MinStack;

MinStack* minStackCreate() {
    MinStack* obj = (MinStack*)malloc(sizeof(MinStack));
    obj->top = NULL;
    return obj;
}

void minStackPush(MinStack* obj, int val) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->val = val;
    
    if (obj->top == NULL || val < obj->top->minVal) {
        newNode->minVal = val;
    } else {
        newNode->minVal = obj->top->minVal;
    }
    
    newNode->next = obj->top;
    obj->top = newNode;
}

void minStackPop(MinStack* obj) {
    if (obj->top == NULL) {
        return;
    }
    
    Node* temp = obj->top;
    obj->top = obj->top->next;
    free(temp);
}

int minStackTop(MinStack* obj) {
    if (obj->top == NULL) {
        return -1; // 栈为空时返回特定值
    }
    return obj->top->val;
}

int minStackGetMin(MinStack* obj) {
    if (obj->top == NULL) {
        return -1; // 栈为空时返回特定值
    }
    return obj->top->minVal;
}

void minStackFree(MinStack* obj) {
    while (obj->top != NULL) {
        Node* temp = obj->top;
        obj->top = obj->top->next;
        free(temp);
    }
    free(obj);
}

int main() {
    MinStack* obj = minStackCreate();
    minStackPush(obj, -2);
    minStackPush(obj, 0);
    minStackPush(obj, -3);
    
    printf("Min element: %d\n", minStackGetMin(obj)); // Output: -3
    
    minStackPop(obj);
    
    printf("Top element: %d\n", minStackTop(obj)); // Output: 0
    
    printf("Min element: %d\n", minStackGetMin(obj)); // Output: -2
    
    minStackFree(obj);
    
    return 0;
}

使用结构体 Node 表示链表节点,每个节点包含元素值 val、当前节点及之前节点中的最小值 minVal,以及指向下一个节点的指针 next。MinStack 结构体中只包含一个指针 top 指向栈顶节点。

通过在节点中记录当前节点及之前节点中的最小值,我们可以实现在常数时间内检索最小元素的功能。

  1. 数组实现
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef struct {
    int *stack;
    int *minStack;
    int top;
} MinStack;

MinStack* minStackCreate() {
    MinStack *obj = (MinStack*)malloc(sizeof(MinStack));
    obj->stack = (int*)malloc(10000 * sizeof(int)); // 假设栈最大容量为 10000
    obj->minStack = (int*)malloc(10000 * sizeof(int));
    obj->top = -1;
    
    return obj;
}

void minStackPush(MinStack* obj, int val) {
    obj->top++;
    obj->stack[obj->top] = val;
    
    if(obj->top == 0 || val <= obj->minStack[obj->top - 1]) {
        obj->minStack[obj->top] = val;
    } else {
        obj->minStack[obj->top] = obj->minStack[obj->top - 1];
    }
}

void minStackPop(MinStack* obj) {
    obj->top--;
}

int minStackTop(MinStack* obj) {
    return obj->stack[obj->top];
}

int minStackGetMin(MinStack* obj) {
    return obj->minStack[obj->top];
}

void minStackFree(MinStack* obj) {
    free(obj->stack);
    free(obj->minStack);
    free(obj);
}

int main() {
    MinStack* obj = minStackCreate();
    minStackPush(obj, -2);
    minStackPush(obj, 0);
    minStackPush(obj, -3);
    
    printf("Min element: %d\n", minStackGetMin(obj)); // Output: -3
    
    minStackPop(obj);
    
    printf("Top element: %d\n", minStackTop(obj)); // Output: 0
    
    printf("Min element: %d\n", minStackGetMin(obj)); // Output: -2
    
    minStackFree(obj);
    
    return 0;
}

使用结构体 MinStack 来表示栈,包括一个存储元素的数组 stack 和一个存储当前最小元素的数组 minStack。通过维护一个辅助栈来保存当前栈中的最小元素。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/274431.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode 79. 单词搜索

心路历程&#xff1a; 做完这道题才发现是回溯&#xff0c;一开始想的是递归&#xff0c;判断完第i个字符后&#xff0c;只需要挨个判断第i1个字符在不在第i个字符的邻域。后来发现由于不能重复使用元素&#xff0c;所以需要维护一个visited列表&#xff0c;并且在遍历所有可能…

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——自适应大邻域算法(ALNS)

基于python语言&#xff0c;采用经典自适应大邻域算法&#xff08;ALNS&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前…

Aigtek超声功率放大器产品介绍

超声功率放大器是一种特殊类型的功率放大器&#xff0c;专门用于增强和放大超声信号的功率。它在医疗、工业和科学领域中得到广泛应用。 一、超声功率放大器的基本概述 超声功率放大器是一种能够将低功率超声信号放大到更高功率水平的设备。它是超声系统的关键组成部分&#xf…

力扣1. 两数之和

思路&#xff1a;用一个map存放 已遍历过的元素和下标&#xff1b; 若当前元素是nums[i], 且该元素的另一半 target-nums[i] 在已遍历过的map里面&#xff0c;则返回两个元素的下标&#xff1b; class Solution {public int[] twoSum(int[] nums, int target) {int[] ans new…

腾讯云服务器多少钱1个月?2024一个月收费阿济格IE吧

2024腾讯云服务器多少钱一个月&#xff1f;5元1个月起&#xff0c;腾讯云轻量服务器4核16G12M带宽32元1个月、96元3个月&#xff0c;8核32G22M配置115元一个月、345元3个月&#xff0c;腾讯云轻量应用服务器61元一年折合5元一个月、4核8G12M配置646元15个月、2核4G5M服务器165元…

数据结构:详解【顺序表】的实现

1. 顺序表的定义 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。动态顺序表与数组的本质区别是——根据需要动态的开辟空间大小。 2. 顺序表的功能 动态顺序表的功能一般有如下几个&#xff1a; 初始化顺序表打印顺序…

PlantUML Integration 编写短信服务类图

PlantUML Integration 写一个类图&#xff0c;主要功能为 1、编写一个serviceSms短信服务类&#xff1b; 2、需要用到短信的地方统一调用基建层的服务即可&#xff1b; 3、可以随意切换、增加短信厂商&#xff0c;不需要更改场景代码&#xff0c;只需要更改application.yml 里面…

Redis数据结构对象中的对象共享、对象的空转时长

对象共享 概述 除了用于实现引用计数内存回收机制之外&#xff0c;对象的引用计数属性还带有对象共享的作用。 在Redis中&#xff0c;让多个键共享同一个值对象需要执行以下两个步骤: 1.将数据库键的值指针指向一个现有的值对象2.将被共享的值对象的引用计数增一 目前来说…

【Godot4.2】2D导航01 - AStar2D及其使用方法

概述 对于2D平台跳跃或飞机大战&#xff0c;以及一些直接用键盘方向键操控玩家的游戏&#xff0c;是根本用不到寻路的&#xff0c;因为只需要检测碰撞就可以了。 但是对于像RTS或战棋这样需要操控玩家到地图指定位置的移动方式&#xff0c;就绝对绕不开寻路了。 导航、碰撞与…

微信小程序接口请求出错:request:fail url not in domain list:xxxxx

一、微信小程序后台和开发者工具配的不一样导致了这个错误 先说结论&#xff1a; 开发者工具配置了https://www.xxx.cn/prod-api/ 微信后台配置了 https://www.xxx.cn 一、最开始 开发者工具配置了https://www.xxx.cn:7500 微信后台配置了 https://www.xxx.cn 报错:reques…

代码随想录算法训练营第53天 | 1143.最长公共子序列 ,1035.不相交的线 ,53. 最大子序和

动态规划章节理论基础&#xff1a; https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 1143.最长公共子序列 题目链接&#xff1a;https://leetcode.cn/problems/longest-common-subsequence/description/ 思路&…

ASP .Net Core ILogger日志服务

&#x1f433;简介 ILogger日志服务是.NET平台中的一个内置服务&#xff0c;主要用于应用程序的日志记录。它提供了灵活的日志记录机制&#xff0c;允许开发者在应用程序中轻松地添加日志功能。以下是其主要特点和组件&#xff1a; ILogger接口&#xff1a;这是ILogger日志服…

电脑数据安全新利器:自动备份文件的重要性与实用方案

一、数据安全的守护神&#xff1a;自动备份文件的重要性 在数字化时代&#xff0c;电脑中的文件承载着我们的工作成果、个人回忆以及众多重要信息。然而&#xff0c;数据丢失的风险无处不在&#xff0c;无论是硬件故障、软件崩溃&#xff0c;还是恶意软件的攻击&#xff0c;都…

JupytetNotebook常用的快捷键

Jupyter Notebook 中常用的快捷键&#xff1a; 切换到命令模式&#xff1a;按 Esc 键。切换到编辑模式&#xff1a;按 Enter 键。运行当前单元格并选择下面的单元格&#xff1a;按 Shift Enter。运行当前单元格并插入新的单元格在下面&#xff1a;按 Alt Enter。删除当前单元…

【Vue3】Vue3中的编程式路由导航 重点!!!

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

test测试类-变量学习

test测试类 作用&#xff1a;标记到类上成为测试类&#xff0c;标记到方法上成为测试方法 变量&#xff1a;测试类的变量&#xff0c;在测试类括号中应用 1、invocationCount变量 意思是这个方法应该被调用的次数。 在测试框架中&#xff0c;特别是当使用参数化测试或数据驱动…

HarmonyOS(鸿蒙)快速入门

一:下载开发工具 鸿蒙的开发工具叫DevEco 下载点击 其他部分都一直next 就行,这个页面出现的install 建议都点击install 然后单独选择安装目录 可能存在的问题 就是之前安装nodejs&#xff08;比如自己开发web或者RN等情况&#xff09;版本低 等情况 所以建议你单独安装一次 …

Avalon总线学习

Avalon总线学习 avalon总线可以分为&#xff1a; Avalon clock interface Avalon reset interface Avalon Memory mapped interface Avalon iterrupt interface Avalon streaming interface Avalon tri-state conduit interface Avalon conduit interface 1、Avalon c…

杨氏矩阵的查找(复杂度<O(N))

题目&#xff1a; 解释&#xff1a;时间复杂度小于O(N)即不要一个一个的去遍历查找。 思路&#xff1a; 一个33的二维数组如图所示&#xff1a; 一&#xff1a;先找到一个最关键的数字&#xff0c;3&#xff08;下标为0,2&#xff09; 关键数的关键之处在于&#xff08;处于…

SpringBoot + MyBatisPlus分页查询

文章目录 1.思路分析2.分页查询后端实现1.com/sun/furn/config/MybatisConfig.java 注入MyBatisPlus分页拦截器2.com/sun/furn/controller/FurnController.java 添加方法3.postman测试 3.分页查询前端实现1.src/views/HomeView.vue 引入分页导航条组件2.src/views/HomeView.vue…
最新文章