当前位置: 首页 > article >正文

【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

相关文章:

  • 深入浅出支持向量机(SVM)
  • W25Q128读写实验(一)
  • 【JavaEE进阶】关于Maven
  • 数据结构:B树与B+树
  • DB-GPT 智谱在线模型配置
  • 笔记本电脑需要一直插着电源吗?电脑一直充电的利弊介绍
  • Leetcode 79. 单词搜索
  • 【进阶五】Python实现SDVRP(需求拆分)常见求解算法——自适应大邻域算法(ALNS)
  • 学习vue3第六节(vue3 中 computed watch watchEffect)
  • 有什么小程序适合个人开发?
  • Aigtek超声功率放大器产品介绍
  • 力扣1. 两数之和
  • 腾讯云服务器多少钱1个月?2024一个月收费阿济格IE吧
  • 数据结构:详解【顺序表】的实现
  • PlantUML Integration 编写短信服务类图
  • 深入挖掘C语言之——枚举
  • Redis数据结构对象中的对象共享、对象的空转时长
  • 【Godot4.2】2D导航01 - AStar2D及其使用方法
  • python企业编码管理的程序(附源码)
  • 微信小程序接口请求出错:request:fail url not in domain list:xxxxx
  • 代码随想录算法训练营第53天 | 1143.最长公共子序列 ,1035.不相交的线 ,53. 最大子序和
  • 5.1.4、【AI技术新纪元:Spring AI解码】Amazon Bedrock
  • ASP .Net Core ILogger日志服务
  • MongoDB聚合运算符:$getField
  • 点云配准9:Colored-ICP的Open3D实现
  • Echarts折线图x轴不显示全部数据的解决办法,亲测有效