题目描述
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) -- 将元素 x 推入栈中。
- pop() -- 删除栈顶的元素。
- top() -- 获取栈顶元素。
- getMin() -- 检索栈中的最小元素。
菜鸡(我的思路)
不就是简单实现一个栈,在通过依次比较不就得到最小值嘛,于是我就这样做了
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 800
typedef struct {
int *data;
int top;
} MinStack;
/** initialize your data structure here. */
MinStack* minStackCreate() {
MinStack *obj=(MinStack *)malloc(sizeof(MinStack));
obj->data=(int *)malloc(MAXSIZE*sizeof(int));
obj->top=-1;
return obj;
}
void minStackPush(MinStack* obj, int x) {
if(obj->top==MAXSIZE-1){
}else{
obj->top++;
obj->data[obj->top]=x;
}
}
void minStackPop(MinStack* obj) {
if(obj->top==-1){
}else{
obj->top--;
}
}
int minStackTop(MinStack* obj) {
if(obj->top==-1){
return 0;
}
return obj->data[obj->top];
}
int minStackGetMin(MinStack* obj) {
if(obj->top==-1) return 0;
if(obj->top==0){
return obj->data[obj->top];
}
int min=obj->data[0];
for(int i=0;i<=obj->top;i++){
if(obj->data[i]<min){
min=obj->data[i];
}
}
return min;
}
void minStackFree(MinStack* obj) {
free(obj->data);
obj->data=NULL;
free(obj);
obj=NULL;
}
int main(){
MinStack *s=minStackCreate();
minStackPush(s,-2);
minStackPush(s,0);
minStackPush(s,-3);
printf("%d\n",minStackGetMin(s));
minStackPop(s);
printf("%d\n",minStackTop(s));
printf("%d\n",minStackGetMin(s));
return 0;
}
渺小的我观看了大神答案
大神结题
“以空间换时间”,使用
辅助栈是常见的做法 理解就是在创建一个栈用于存放最小值,但辅助栈也分为两种
- 同步
思路: 当将元素进栈时,辅助栈也同样添加元素(为第一个就直接添加,不为第一个时,就进行比较,若添加的元素大于辅助栈的栈顶元素,就添加最小元素,小于就添加本来的元素) 复杂度为O(n)
自己写的C语言版本
typedef struct {
int *data;
int *helper;
int top;
}MinStack;
MinStack* minStackCreate(){
MinStack *s=(MinStack *)malloc(sizeof(MinStack));
s->data=(int *)malloc(sizeof(int)*MAXSIZE);
s->helper=(int *)malloc(sizeof(int)*MAXSIZE);
s->top=0;
return s;
}
void minStackPop(MinStack* obj) {
if(obj->top==0){
}else{
obj->top--;
obj->helper[obj->top]=obj->data[obj->top]=NULL;
}
}
void minStackPush(MinStack* obj, int x){
if(obj->top==MAXSIZE){
}else{
if(obj->top==0 || x<obj->helper[obj->top-1]){
obj->helper[obj->top]=x;
}else{
obj->helper[obj->top]=obj->helper[obj->top-1];
}
obj->data[obj->top++]=x;
}
}
int minStackTop(MinStack* obj) {
if(obj->top==0){
return 0;
}
return obj->data[obj->top-1];
}
int minStackGetMin(MinStack* obj) {
if(obj->top==0) {
return 0;
}else{
return obj->helper[obj->top-1];
}
}
void minStackFree(MinStack* obj) {
free(obj->data);
free(obj->helper);
obj->data=NULL;
obj->helper=NULL;
free(obj);
obj=NULL;
}
大神的原码:使用Python实现,看着就简单
作者:liweiwei1419 链接:leetcode-cn.com/problems/mi…
class MinStack:
# 辅助栈和数据栈同步
# 思路简单不容易出错
def __init__(self):
# 数据栈
self.data = []
# 辅助栈
self.helper = []
def push(self, x):
self.data.append(x)
if len(self.helper) == 0 or x <= self.helper[-1]:
self.helper.append(x)
else:
self.helper.append(self.helper[-1])
def pop(self):
if self.data:
self.helper.pop()
return self.data.pop()
def top(self):
if self.data:
return self.data[-1]
def getMin(self):
if self.helper:
return self.helper[-1]
- 不同步: 思路与之前的有一丢丢不同,对第一种的改进,减少空间浪费
注意点
- 1:辅助栈的元素空的时候,必须放入新进来的数
- 2:新来的数小于或者等于辅助栈栈顶元素的时候,才放入(特别注意这里等于要考虑进去)
原因就是:
如果取消等于这个条件,当pop掉这个元素时,本应该没有这个元素了,但你的最小栈里还保留着,很可能冲突 - 3:出栈的时候,辅助栈的栈顶元素等于数据栈的栈顶元素,才出栈,即"出栈保持同步"就可以了
另一种思路
只利用一个栈,每一次执行push操作时,进行两次入栈,第一次入栈此元素,第二次入栈此时栈中最小的元素;执行pop操作与之相对:将剩余元素遍历一遍,找到最小值,并push到栈中
复杂度: O(n)
typedef struct {
int *data;
int top;
} MinStack;
/** initialize your data structure here. */
MinStack* minStackCreate() {
MinStack *obj=(MinStack *)malloc(sizeof(MinStack));
obj->data=(int *)malloc(MAXSIZE*sizeof(int));
obj->top=-1;
return obj;
}
void minStackPush(MinStack* obj, int x) {
if(obj->top==MAXSIZE-1){
}else if(obj->top==-1){
obj->top++;
obj->data[obj->top]=x;
obj->top++;
obj->data[obj->top]=x;
}else{
int tmp=obj->data[obj->top];
obj->top++;
obj->data[obj->top]=x;
if(tmp<x){
obj->top++;
obj->data[obj->top]=tmp;
}else{
obj->top++;
obj->data[obj->top]=x;
}
}
}
void minStackPop(MinStack* obj) {
if(obj->top==-1){
}else{
obj->top--;
obj->top--;
int i;
int min=obj->data[0];
for(i=1;i<obj->top-1;i++){
if(obj->data[i]<min){
min=obj->data[i];
}
}
obj->data[obj->top]=min;
}
}
int minStackTop(MinStack* obj) {
if(obj->top==-1){
return 0;
}
return obj->data[obj->top-1];
}
int minStackGetMin(MinStack* obj) {
return obj->data[obj->top];
}
void minStackFree(MinStack* obj) {
free(obj->data);
obj->data=NULL;
free(obj);
obj=NULL;
}
总结
学习算法要敢于想象,从多种方向思考