堆栈中的最小元素

本文介绍了如何设计一个自定义栈结构,使得在push、pop和查找最小元素操作上的时间复杂度都为O(1)。通过维护一个辅助栈minStack来记录主栈stack中最小元素的位置,当元素出栈时,同时检查是否为最小元素并相应更新minStack。C#代码实现展示了这个数据结构的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2. 设计包含min函数的栈。
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小(大)元素。

要求函数min、push以及pop的时间复杂度都是O(1)。

解析:本题要求自定义栈结构及操作(push,pop等),无论入栈多少个元素,元素的具体值为多少,在pop(n>=0次)操作后都可以通过自定义的FinMin()找到当前栈中的最小(大)元素。


思路:借助辅助栈。栈stack 用于存储入栈元素,栈minStack 用于记录stack栈中最小元素在stack中的位置。

           (1).第一个将要进入stack栈的元素同样也要进入到minSstck栈中

           (2).此后,元素直接进入stack栈中,而 进入minStack栈的元素arg要满足 arg < stack[minStack[minStack.Count - 1]]条件。

           因此可以写成 :

          stack.push(arg);

          if( minStack.IsEmpty() || arg < stack[minStack[minStack.Count - 1] ] ) { minStack.Push( stack.Count - 1 ) } ( 以上为伪码,具体语言具体实现)

          这样一来,minStack中记录的是stack当前栈中元素的最小值(第一次出现)在该栈中的位置。

         那么stack中有元素出栈之后,minStack是如何保持栈顶元素为stack栈中元素最小值的呢?

         每当 stack有元素a出栈时,就要和minStack中记录的对应位置的值进行比较,若a大于等于minStack中记录位置的值,则只管出栈;若是小于则

         minStack也要执行Pop操作。那么此时的minStack栈顶元素即为 stack栈中的最小值对应的坐标。


        具体见原文:  http://blog.youkuaiyun.com/v_july_v/article/details/6126406   第二题;

        以下为c#实现代码(初学c#,实现的很憋足,望指正):


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace MS100
{
    class Program
    {
        public class FindMin<T>
        {
            private List<int> minStack = new List<int>();
            private List<T> stack = new List<T>();

            public void Push(T arg)
            {
                stack.Add(arg);

                if(minStack.Count == 0 || CompareToInt(arg , stack[minStack.Count - 1]) < 0)
                {
                    minStack.Add(stack.Count - 1);
                }
            }

            public void Pop()
            {
                if ( CompareToInt(stack[stack.Count - 1] , stack[minStack[minStack.Count - 1]]) == 0 )
                {
                    stack.RemoveAt(stack.Count - 1);
                    minStack.RemoveAt(minStack.Count - 1);
                }
            }

            public T min()
            {
                return stack[minStack[minStack.Count - 1]];
            }

            public int CompareToInt(T arg1 , T arg2)
            {
                object larg = (object)arg1;
                object rarg = (object)arg2;

                return ((int)larg).CompareTo((int)rarg);
            }
        }

        static void Main(string[] args)
        {
            FindMin<int> a = new FindMin<int>();
            a.Push(2);
            a.Push(3);
            a.Push(6);
            a.Push(1);
            
            Console.WriteLine(a.min().ToString());

            a.Pop();
            Console.WriteLine(a.min().ToString());
            Console.ReadKey();
        }
}

参考资料:http://blog.youkuaiyun.com/v_july_v/article/details/6126406

            希望能帮到像我一样的初学者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值