《程序员面试金典(第6版)》面试题 03.05. 栈排序
创始人
2024-05-31 14:42:55

题目描述

栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。

示例1:

  • 输入:
    [“SortedStack”, “push”, “push”, “peek”, “pop”, “peek”]
    [[], [1], [2], [], [], []]
    输出:
    [null,null,null,1,null,2]

示例2:

  • 输入:
    [“SortedStack”, “pop”, “pop”, “push”, “pop”, “isEmpty”]
    [[], [], [], [1], [], []]
    输出:
    [null,null,null,null,null,true]

题目解析

使用辅助栈法

先设置主栈为st,辅助栈为help。如果主栈为空,我们直接往主栈中遍历元素。如果主栈中有元素,则逐一比较与栈顶元素的大小。如果这个值大于栈顶元素,则栈顶元素弹出,并压入辅助栈中。如果这个元素小于等于主栈顶元素了话,我们就直接往主栈中添加元素。

具体实现看代码:

class SortedStack {
public:stack st;stack help;SortedStack() {}void push(int val) {while(!st.empty() && val > st.top()){help.push(st.top());st.pop();}st.push(val);while(!help.empty()){st.push(help.top());help.pop();}}void pop() {if(st.empty()) return;st.pop();return;}int peek() {if(st.empty()) return -1;return st.top();}bool isEmpty() {return st.empty();}
};/*** Your SortedStack object will be instantiated and called as such:* SortedStack* obj = new SortedStack();* obj->push(val);* obj->pop();* int param_3 = obj->peek();* bool param_4 = obj->isEmpty();*/

复杂度分析:
时间复杂度:push方法的时间复杂度最小为O(1),最大为O(2N),其中N是压入栈的元素。push方法均摊下来的时间复杂度为O(N)。pop,peek,isempty方法的时间复杂度均是O(1)
空间复杂度:我们需要用到两个栈,我们需要往这个栈中添加元素。所以空间复杂度为O(N),N为往栈中压的元素数量。

不使用辅助栈法

那如何不使用辅助栈呢?我觉得大家心里大概会有一个答案。那就是递归!!!

那首先,我先来说一下,我理解的递归函数三要素是什么

  1. 确定递归函数的返回值与形参是什么?
  2. 确定递归函数的终止条件
  3. 将要解决的大问题,拆分为更简单的且相同的小问题,也就是单层递归的逻辑。

然后我们来看这道题。
那对于这道题来说,我们要做的就是,使栈中的元素从顶到底,永远是按照从小到大排列。
那么我们要解决的大问题就是将栈中的元素从顶到底,永远是从小到大排列。那小问题是什么呢?小问题就是,我们每次都要去比较要压入栈的元素与栈顶的元素去做比较。如果大于栈顶元素,就继续递归。如果小于,就直接添加到栈顶。

我们现在将单层递归的逻辑想清楚了后,那我们想一想递归函数如何结束呢?那当然是将val加入栈后,就结束了啊。

最后我们来想想这个函数需要什么返回值,与形参。那么根据这道题,我发现直接使用原函数的push方法就行了。

ok,想明白这所有的问题后,就不难写出代码了,下面是具体的代码:

class SortedStack {
public:stack st;SortedStack() {}void push(int val) {if(!st.empty() && val > st.top()){int temp = st.top();st.pop();push(val);st.push(temp);return ;}st.push(val);return;}void pop() {if(!st.empty()) st.pop();return ;}int peek() {if(st.empty()) return -1;return st.top();}bool isEmpty() {return st.empty();}
};

复杂度分析:
时间复杂度:push方法的时间复杂度为O(n),n为要添加进栈的元素。pop,peek,isempty方法的时间复杂度均为O(1)。
空间复杂度:O(n) ,n是压入栈的元素

总结

这道题需要我们对栈这种数据结构的用法要比较了解。同时对递归函数的写法要心中有思路。做到了这两点,这道题其实没有什么难度。

相关内容

热门资讯

苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...