小镇做题家|在 O(1)的时间内找到栈的最值

这是一篇关于如何在C语言中实现一个栈,其min、push和pop操作时间复杂度均为O(1)的博客。博主分享了在字节跳动面试时遇到的真题——在栈中找到最小元素,并提供了解题思路和代码实现。通过维护两个栈,一个存储所有元素,另一个存储最小元素,从而在元素变动时仍能保持O(1)的时间复杂度获取最小值。
摘要由CSDN通过智能技术生成

题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

这道题目是我在字节面试时遇到的真题,当初没想到最优解,复盘的时候发现是道简单题。。把这道题目作为栈的使用分享给大家!(在面试的时候没有想到最优解就先选择一个次优的解法,总比做不出来要好!)

传送门

LeetCode:剑指 Offer 30. 包含 min 函数的栈

解题思路

栈可以看作是一个数组,在一个数组中找一个最值是很简单的,我们只需要遍历这个数组即可。在要求 O(1)时间内时,我们在进行数组赋值的时候记录下最值即可满足要求。但是要求在元素发生变动的时候也满足 O(1)的话,我们可以保存每次入栈时的最值。即用空间换时间!

图解:


--------------------------------
values | 0 | -1 | 10 | -2 | -2 |
--------------------------------
min    | 0 | -1 | -1 | -2 | -2 |
--------------------------------

从注释中可以看出,我们在添加元素的时候将传入的值与当前栈的最值进行判断即可得知在添加新元素之后栈的最值

解题代码

主体代码
#include <stdio.h>
#include <stdlib.h>

typedef struct MinStack
{
    /* data */
    int len;     // 元素长度
    int index;   // 新元素下标
    int *values; // 值数组
    int *min;    // 最值数组
} MinStack;

// 初始化
MinStack *init(int size)
{
    // 申请空间
    MinStack *stack = malloc(sizeof(MinStack));
    // 初始化值
    stack->index = 0;
    stack->len = 0;
    stack->values = malloc(sizeof(int) * size);
    stack->min = malloc(sizeof(int) * size);
    return stack;
}

//  入栈操作
void push(MinStack *stack, int val)
{
    // 指针为空直接返回
    if (stack == NULL)
    {
        return;
    }
    // 将元素进行保存
    stack->values[stack->index] = val;
    // 判断最值
    if (stack->len > 0)
    {
        // 存在元素就与当前栈的最值进行比较
        int lastMin = stack->min[stack->index - 1];
        if (lastMin < val)
        {
            stack->min[stack->index] = lastMin;
        }
        else
        {
            stack->min[stack->index] = val;
        }
    }
    else
    {
        // 栈为空直接设置为最值
        stack->min[stack->index] = val;
    }
    stack->index++;
    stack->len++;
}

// 出栈操作
int pop(MinStack *stack)
{
    // 栈为空
    if (stack == NULL || stack->len < 1)
    {
        return 0xFFFFFF;
    }
    // 出栈
    int val = stack->values[stack->index - 1];
    // 更新下标和长度
    stack->len--;
    stack->index--;
    return val;
}

// 获取最小值
int min(MinStack *stack)
{
    // 直接返回最值
    return stack->min[stack->index - 1];
}

// 销毁栈对象
void destory(MinStack *stack)
{
    //释放空间 重置数据
    stack->index = stack->len = 0;
    free(stack->min);
    free(stack->values);
}
测试函数
int main()
{
    MinStack *stack = init(100);
    push(stack, 1);
    printf("min=%d\n", min(stack));
    push(stack, -1);
    push(stack, 100);
    printf("min=%d\n", min(stack));
    printf("pop=%d\n", pop(stack));
    printf("len=%d\n", stack->len);
    return 0;
}

最近我也在用 Go 刷算法题攒代码熟练度,再结合一些数据结构的知识新开了这个系列。后续将会继续更新!

文中的代码我已上传到 gitlab:
https://gitlab.com/BitLegend/c-data-structure.git

以上就是本期的全部内容,感谢你的阅读!我们春节见,会有一些大的改动以及总结和在牛年的一些计划!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值