算法与数据结构面试分享(二十)设计一个带有min函数的栈

这是一道google的面试题。请帮忙定义一个栈,要求添加一个min函数,能够得到栈里的最小元素。要求min, push, pop的时间复杂度都是O(1).

我们可不可以保存一个临时变量,每次入栈的时候拿入栈的元素和当前最小值去做比较,如果比当前的元素小我们就替换。好像目前是工作的,但是再往下想,如果我现在出栈呢?大家知道,栈里肯定有一个相对较小的元素,而此时,我们已经不知道它是多少呢?所以这种方法是不工作的。

继续往下,刚才的思路中,我们如果能保存每一个比较小的元素,而且出栈的时候我们就抹掉它好像就可以了哈。所以大家想到了什么?似乎要使用另外一个栈,保存较小的元素。那我们一起看下这张表,入栈和出栈的过程中,最小值分别是什么?

步骤栈内元素(右边是顶)操作当前最小最小元素辅助栈(右边是顶)
14入栈444
24,1入栈114,1
34,1,5入栈514,1
44,1出栈514,1
54出栈144
64,0入栈004,0
74, 0, -2入栈-2-24, 0, -2

所以,大家发现没有:

入栈:我们需要拿当前元素和辅助栈的顶端元素比较,如果当前值更小(或相等),我们就入辅助栈,否则不操作

出栈:如果当前出栈的元素和辅助栈的顶端元素比较,如果相等,我们辅助栈也出栈,否则不操作

取最小:我们不需要出栈,直接返回它的值

好了,我们就用一个列表来实现这个栈吧,第一个元素表示栈底,最后一个元素是栈顶哈。一起看代码(当然我们还可以用其他的等多基础结构定义栈哈):

  public class MyStack
    {
        private List<int> stackList = new List<int>();
        private List<int> helpStack = new List<int>();

        public int Min()
        {
            if (helpStack.Count > 0)
            {
                return helpStack.Last();
            }

            throw new IndexOutOfRangeException();
        }

        public void Push(int e)
        {
            stackList.Add(e);

            if (helpStack.Count == 0 || (helpStack.Count > 0 && helpStack.Last() >= e))
            {
                helpStack.Add(e);
            }

        }

        public int Pop()
        {
            if (stackList.Count > 0)
            {
                int e = stackList.Last();
                stackList.RemoveAt(stackList.Count - 1);

                if (helpStack.Count > 0 && helpStack.Last() == e)
                {
                    helpStack.RemoveAt(helpStack.Count - 1);
                }

                return e;
            }

            throw new IndexOutOfRangeException();
        }
    }

好了,大家如果有更好的解法,欢迎提出来我们一起讨论哈。也欢迎大家关注我们的视频教程。

算法与数据结构

算法与数据结构-微软经典面试题

关注我们的公众号,加入QQ群讨论:

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值