微软面试题:设计包含min函数的栈

hoomey 2011-03-23 10:31:23
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
要求函数min、push以及pop的时间复杂度都是O(1)。

不知道这个题目在这里讨论过没,大家一起研究研究~~ 共同学习共同进步
...全文
1116 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
xx77009833 2011-04-19
  • 打赏
  • 举报
回复
为每个元素弄一个辅助空间,记录当前栈中最小值
比如大概这样
struct stack{
int value;
int min;
}
每次push时,都把栈顶元素的min成员与待push元素比较,小的存入待插入元素的min成员里面
这样求min的时候只需要取栈顶元素的min成员即可

这个思路有问题么??怎么感觉不像网上说的需要额外的栈来做存储啊
fx397993401 2011-03-26
  • 打赏
  • 举报
回复
对于每个栈 的元素 设置一个指针 这个指针指向比他小的那个元素 设置一个指针指向最小的

对于pop push 操作需要对指针进行相应的操作
hzc543806053 2011-03-26
  • 打赏
  • 举报
回复
有点挑战性
huacong20082009 2011-03-26
  • 打赏
  • 举报
回复
1 #define MAX_SIZE 100
2 #define MAX 65535
3
4 struct stackDef
5 {
6 int array[MAX_SIZE];
7 int top;
8 int min;
9 int secMin;
10 };
11 struct stackDef minStack;
12 int init(struct stackDef *para);
13 int push(struct stackDef *para,const int x);
14 int pop(struct stackDef *para,int *x);
15 int min(struct stackDef *para,int *x);
1 #include "stackDef.h"
2
3 int init(struct stackDef *para)
4 {
5 int i ;
6 for(i = 0;i < MAX_SIZE;i++)
7 para->array[i] =0;
8 para->top = -1;
9 para->min = MAX;
10 para->secMin = MAX;
11 return 0;
12 }
13
14 int push(struct stackDef *para,const int x)
15 {
16 para->top ++;
17 para->array[para->top] = x;
18 if(x < para->min)
19 {
20 para->min = x;
21 minStack.array[++minStack.top] = x;
22 }
23 return 0;
26 int pop(struct stackDef *para,int *x)
27 {
28 *x = para->array[para->top];
29 para->top--;
30 if(*x == para->min)
31 {
32 para->min = minStack.array[--minStack.top];
33 }
34 return 0;
35 }
36
37 int min(struct stackDef *para,int *x)
38 {
39 *x = para->min;
40 return 0;
41 }
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "stackDef.h"
4
5 int main()
6 {
7 struct stackDef ss;
8 int i ,mi;
9 init(&minStack);
10 init(&ss);
11 for(i = 0; i < 10; i++)
12 push(&ss,10 -i);
13 min(&ss,&mi);
14 printf("The mimimal elment is %d\n",mi);
15 for(i = 0;i < 5; i++)
16 pop(&ss,&mi);
17 min(&ss,&mi);
18 printf("The mimimal elment is %d\n",mi);
19 return 0;
20 }

hoomey 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 quwei197874 的回复:]
去看<编程之美>
[/Quote]
[Quote=引用 10 楼 ayw215 的回复:]
这个题目很简单。。。
我去BD的笔试题里面就有这个,自己多想想吧。网上也有答案的
[/Quote]
我要的不是答案,只是想跟大家探讨一下,或许有更好的解法。
一起学习,共同进步~~
willabc 2011-03-25
  • 打赏
  • 举报
回复
14楼的很好!
tangxianghenggood 2011-03-25
  • 打赏
  • 举报
回复
可以先给每个元素附上一个下标似的标记,在进栈的时候比较大小 进行卡选择 用一个变量保存小值的标记值,元素直接进,到要pop的时候 根据标记数应该可以确定min了 这个方法不知行不
qq120848369 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 qwlong007 的回复:]

引用 16 楼 qq120848369 的回复:
编程之美上的题目,很简单的.

stack有O(1)时间获取最小值的办法,就是维护一个最小值链表,但这个很讲究,不是所有栈里元素都在链表里哦,只有曾经在push时刻夺取到min的结点才会加入到链表记录当中.


C/C++ code
#include <iostream>

class Stack //只为演示算法,不考虑……
[/Quote]

哎,我看着编程之美敲上来的,让你一说又不是O(1)了,别自相矛盾。
quwei197874 2011-03-25
  • 打赏
  • 举报
回复
去看<编程之美>
guyu2011 2011-03-25
  • 打赏
  • 举报
回复
如果是对元素的要求没有限制,可以在push函数时,就将栈内元素排序
第一个元素当然不用
以后每次push一个元素之前,将要push的元素与栈顶元素比较,如小则直接入栈,
反之,先pop,再push,再push pop出的元素。

不过这个这个与栈的原则相违背了,栈就是要First In Last Out
screwzm 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 redhumor 的回复:]

大家为什么那么纠结?
:1,在Stack类中定义一个static 变量——保存最小值,他要你定义个栈的数据结构,所以 加个 static 变量不就OK了?
……大家是不是想复杂了,题目的 意思是不是重新定义 stack的 结构……如果是 我的说法就没错吧
[/Quote]
那你pop之后重新给这个成员赋值的时候复杂度不就不是o(1)了啊?!
5L和后面很多是正解!
学习了!谢谢楼主!
lappa 2011-03-25
  • 打赏
  • 举报
回复
我怎么觉的前面的所有答案和代码都不能实现这个功能呢。
如果push值依次是 2 3 4 5 6 7 8 9
那么pop的值也应该依次是 2 3 4 5 6 7 8 9吧。

我认为这个栈的模拟有点像要做一个小顶堆。
中间用一个平衡2叉数维护。时间复杂度是O(LogN)
zhusizhi007 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 qq120848369 的回复:]
编程之美上的题目,很简单的.

stack有O(1)时间获取最小值的办法,就是维护一个最小值链表,但这个很讲究,不是所有栈里元素都在链表里哦,只有曾经在push时刻夺取到min的结点才会加入到链表记录当中.


C/C++ code
#include <iostream>

class Stack //只为演示算法,不考虑栈溢出与栈空等特殊情况,不考虑类的设计风格
{
p……
[/Quote]
但是算法的复杂度应该不是n(1)了。
qq120848369 2011-03-25
  • 打赏
  • 举报
回复
因为万一栈顶是MIN,被POP掉后谁又是MIN呢,所以需要作特殊记录。 楼上懂了?
redhumor 2011-03-25
  • 打赏
  • 举报
回复
大家为什么那么纠结?
:1,在Stack类中定义一个static 变量——保存最小值,他要你定义个栈的数据结构,所以 加个 static 变量不就OK了?
……大家是不是想复杂了,题目的 意思是不是重新定义 stack的 结构……如果是 我的说法就没错吧
anqingxuexi 2011-03-25
  • 打赏
  • 举报
回复
那如果push的数本来就是逆序的,那么在最小值链表中不也是所有栈中的数了
qq120848369 2011-03-24
  • 打赏
  • 举报
回复
编程之美上的题目,很简单的.

stack有O(1)时间获取最小值的办法,就是维护一个最小值链表,但这个很讲究,不是所有栈里元素都在链表里哦,只有曾经在push时刻夺取到min的结点才会加入到链表记录当中.

#include <iostream>

class Stack //只为演示算法,不考虑栈溢出与栈空等特殊情况,不考虑类的设计风格
{
public:
Stack():size(0),minIndex(-1)
{
link[0]=-1;
}

int min()
{
return size==0 ? (int)1e6:stack[minIndex];
}

void push(int n)
{
if(n<min())
{
link[size]=minIndex;
minIndex=size;
}
else
{
link[size]=-1;
}

stack[size++]=n;
}

int pop()
{
if(minIndex==size-1)
{
minIndex=link[minIndex];
}

return stack[--size];
}

private:
enum
{
SIZE=100
};

int stack[SIZE];
int link[SIZE];
int size,minIndex;
};

int main()
{
Stack s;
s.push(2);
s.push(1);
s.push(7);
s.push(8);

for(int i=0;i<4;++i)
{
std::cout<<s.min();
std::cout<<" "<<s.pop()<<std::endl;
}

return 0;
}

hoomey 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 delphiwcdj 的回复:]
引用 12 楼 delphiwcdj 的回复:

把最小的元素放在栈顶

用空间换取时间
[/Quote]

这样做的话,push和pop就不好实现了
yoxibaga 2011-03-24
  • 打赏
  • 举报
回复

#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#define Maxsize 10
typedef struct
{
int a[Maxsize];
int top;
}Sqstack;
typedef struct
{
int b[Maxsize];
int top;
}Minstack;
void Push(Sqstack *&s,int num)
{
if(s->top > Maxsize-1)
{
printf("stack is full!\n");
exit(0);
}
s->top++;
s->a[s->top] = num;
}
void Push(Minstack *&t,int num)
{
if(t->top > Maxsize-1)
{
printf("stack is full!\n");
exit(0);
}
t->top++;
t->b[t->top] = num;
}
int Pop(Sqstack *&s)
int Pop(Sqstack *&s,Minstack *&t)
{
int k,num;
if(s->top == -1)
{
printf("stack is empty!\n");
exit(0);
}
num = s->a[s->top--];
k = Gettop(t);
if(k == num)
Pop(t);
return num;
}
int Pop(Minstack *&t)
{
int num;
if(t->top == -1)
{
printf("stack is empty!\n");
exit(0);
}
num = t->b[t->top--];
return num;
}
int Gettop(Minstack *s)
{
return s->b[s->top];
}
int main()
{
int i,k,num;
Sqstack *s;
Minstack *t;
s = (Sqstack*)malloc(sizeof(Sqstack));
s->top = -1;
t = (Minstack*)malloc(sizeof(Minstack));
t->top = -1;
scanf("%d",&num);
Push(s,num);
Push(t,num);
for(i = 1;i < Maxsize; i++)
{
scanf("%d",&num);
Push(s,num);
k = Gettop(t);
if(num < k)
Push(t,num);
}
min = Min(s,t);
/* while(s->top != -1)
{
k = Pop(s);
printf("%d ",k);
}
printf("\n");
while(t->top != -1)
{
k = Pop(t);
printf("%d ",k);
}
*/
getch();
return 0;
}

//Minstack栈顶元素就是Sqstack的最小元素,当Pop(Sqstack)时,若满足Pop(Sqstack)与
//GetTop(Minstack)相等,则Pop(Minstack);这样就能满足Minstack的栈顶元素始终
//是Sqstack的最小元素
delphiwcdj 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 delphiwcdj 的回复:]

把最小的元素放在栈顶
[/Quote]
用空间换取时间
加载更多回复(12)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧