栈和队列算法总结

二、栈和队列

 

       目录:

       1.设计含min函数的栈,要求min、push和pop的时间复杂度都是o(1)。

       2.设计含min函数的栈的另解

       3.用两个栈实现队列

       4.用两个队列实现栈

 

       5.栈的push、pop序列是否一致

       6.递归反转一个栈,要求不得重新申请一个同样的栈,空间复杂度o(1)

       7.给栈排个序

       8..如何用一个数组实现两个栈

       9..如何用一个数组实现三个栈

 

 

1.设计含min函数的栈,要求min、push和pop的时间复杂度都是o(1)。

算法思想:需要设计一个辅助栈,用来存储当前栈中元素的最小值。网上有人说存储当前栈中元素的最小值的所在位置,虽然能节省空间,这其实是不对的,因为我在调用Min函数的时候,只能得到位置,还要对存储元素的栈不断的pop,才能得到最小值——时间复杂度o(1)。

所以,还是在辅助栈中存储元素吧。

此外,还要额外注意Push操作,第一个元素不用比较,自动成为最小值入栈。其它元素每次都要和栈顶元素比较,小的那个放到栈顶。

 

public class NewStack

{

   private Stack dataStack;

   private Stack mindataStack;

public NewStack()

    {

       dataStack = new Stack();

       mindataStack = new Stack();

    }

public void Push(int element)

    {

       dataStack.Push(element);

if (mindataStack.Count == 0)

           mindataStack.Push(element);

       else if (element <= (int)mindataStack.Peek())

           mindataStack.Push(element);

       else //(element > mindataStack.Peek)

           mindataStack.Push(mindataStack.Peek());

    }

   

   public int Pop()

    {

       if (dataStack.Count == 0)

           throw new Exception("The stack is empty");

       

       mindataStack.Pop();

       return (int)dataStack.Pop();

    }

public int Min()

    {

       if (dataStack.Count == 0)

           throw new Exception("The stack is empty");

       

       return (int)mindataStack.Peek();

    }

}

 

 

 

2.设计含min函数的栈的另解

话说,和青菜脸呆久了,就沾染了上海小市民意识,再加上原本我就很抠门儿,于是对于上一题目,我把一个栈当成两个用,就是说,每次push,先入站当前元素,然后入栈当前栈中最小元素;pop则每次弹出2个元素。

算法代码如下所示(这里最小元素位于当前元素之上,为了下次比较方便):

public class NewStack

{

   private Stack stack;

public NewStack()

    {

       stack = new Stack();

    }

public void Push(int element)

    {

       if (stack.Count == 0)

       {

           stack.Push(element);

           stack.Push(element);

       }

       else if (element <= (int)stack.Peek())

       {

           stack.Push(element);

           stack.Push(element);

       }

       else //(element > stack.Peek)

       {

           object min = stack.Peek();

           stack.Push(element);

           stack.Push(min);           

       }

    }

public int Pop()

    {

       if (stack.Count == 0)

           throw new Exception("The stack is empty");

stack.Pop();

       return (int)stack.Pop();

    }

public int Min()

    {

       if (stack.Count == 0)

           throw new Exception("The stack is empty");

return (int)stack.Peek();

    }

}

 

 

之所以说我这个算法比较叩门,是因为我只使用了一个栈,空间复杂度o(N),节省了一半的空间(算法1的空间复杂度o(2N))。

 

 

 

 

3.用两个栈实现队列

实现队列,就要实现它的3个方法:Enqueue(入队)、Dequeue(出队)和Peek(队头)。

       1)stack1存的是每次进来的元素,所以Enqueue就是把进来的元素push到stack1中。

       2)而对于Dequeue,一开始stack2是空的,所以我们把stack1中的元素全都pop到stack2中,这样stack2的栈顶就是队头。只要stack2不为空,那么每次出队,就相当于stack2的pop。

       3)接下来,每入队一个元素,仍然push到stack1中。每出队一个元素,

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值