题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 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
以上就是本期的全部内容,感谢你的阅读!我们春节见,会有一些大的改动以及总结和在牛年的一些计划!