【IT笔试面试题整理】堆栈和队列
如何准备:
Whether you are asked to implement a simple stack / queue, or you are asked to implementa modified version of one, you will have a big leg up on other candidates if you can flawlessly work with stacks and queues Practice makes perfect! Here is some
skeleton code for a Stackand Queue class
当面试官需要你实现一个简单的堆栈或者列队的时候,你能顺利的写完,那你就比一般的应聘者先人一步了。熟能生巧,下面的这些基本的堆栈和队列的框架代码一定要掌握。
Implementing a Stack
堆栈
1 class Stack {2 Node top;3 Node pop() {4 if (top != null) {5 Object item = top.data;6 top = top.next;7 return item;8 }9 return null;10 }11 void push(Object item) {12 Node t = new Node(item);13 t.next = top;14 top = t;15 }16 }
Implementing a Queue
队列
1 class Queue {2 Node first, last;3 void enqueue(Object item) {4 if (!first) {5 back = new Node(item);6 first = back;7 } else {8 back.next = new Node(item);9 back = back.next;10 }11 }12 Node dequeue(Node n) {13 if (front != null) {14 Object item
= front.data;15 front = front.next;16 return item;17 }18 return null;19 }20 }
3 1 Describe how you could use a single array to implement three stacks
3.1 怎样用一个数组实现三个堆栈
3.1解答:
解法一:
将数组划分成3等份,每一份独立的用来实现堆栈。
*第一个堆栈:从 0 至 n/3
*第二个堆栈:从 n/3 至 2n/3
*第三个堆栈:从2n/3 至 n
这种解法是基于对每个堆栈的使用没有额外的使用说明,所以我们直接为每个堆栈划分固定的大小。
解法二:
解法二中的,主要数组中还有空余的空间,堆栈就还能增长。
每次为堆栈分配一个空间的时候,在这个新空间中记录上一个空间地址。这样堆栈中的每个元素都有一个指针指向之前的元素。
这样的实现方法有一个问题就是如果一个堆栈弹出一个空间(释放空间),这个空间并不会作为空闲空间现在数组后面。这样话我们就不能使用新产生的空闲空间。
为了解决这个问题,我们用一个列表来记录空闲的空间。当有新空闲空间出现,我们就把它加入到这个表中。如果需要新分配一个空间,就从这个表中删除一个元素。
这样的实现方法使得3个堆栈能够动态的使用数组的空间,但是这是以增大空间复杂度换来的。
3 2 How would you design a stack which, in addition to push and pop, also has a function min which returns the minimum element? Push, pop and min should all operate in O(1) time
3.2 适合实现一个堆栈,除了有函数push、pop函数之外还有min函数,min函数范围堆栈中的最小元素。要求push,pop和min三个函数的时间复杂度均为O(1)。
3.2解答:
在每个堆栈中的节点中记录目前堆栈中的最小值。那么调用min( )函数时只需要看看栈顶元素中记录的最小值即可。
但是这样解法存在的问题是,如果堆栈的需要记录的元素非常多,那么这样的方法将会消耗大量的空间。因为我们在每个堆栈的元素中都记录来了最小值。这个能不能改进呢?
我们可以在创建一个辅助的堆栈只用来记录最小的元素。
这样的方法就是不是有更高的效率呢,在堆栈s2中只记录最小值,避免了大量的冗余数据的记录。
3 3 Imagine a (literal) stack of plates If the stack gets too high, it might topple There- fore, in real life, we would likely start a new stack when the previous stack exceeds some threshold Implement a data structure SetOfStacks that mimics this
SetOf- Stacks should be composed of several stacks, and should create a new stack once the previous one exceeds capacity SetOfStacks push() and SetOfStacks pop() should behave identically to a single stack (that is, pop() should return the same values as it
would if there were just a single stack) FOLLOW UP Implement a function popAt(int index) which performs a pop operation on a specific sub-stack
3.3 想象下啊:一堆盘子,如果堆得太高的话,就容易倒下来。所以在现实中如果盘子堆到一定高度,我们就会重新起一个堆。现在实现一个新的数据结构来模拟这样现象。SetOfStack当中包含很多的堆栈,当一个堆栈达到上限的时候,启用下一个堆栈。SetOfStack.push 和 SetOfStack.pop应该和普通堆栈的操作一样。
进阶:
实现一个函数popAt(int index),指定在哪个堆栈上弹出元素。
3.3解答:
根据题意,我们的数据结构大体上应该是这么一个框架:
由于要和普通的堆栈的push()有相同的效果,也就是说每次push()都必须将元素放到最近使用的一个堆栈中。但是在这个堆栈已经满了情况下,那就必须建一个新的堆栈然后再入栈。那么push的实现如下:
那pop()如何实现呢?和push()差不多,也一定要在最近的一个堆栈上操作。但是如果最后一个堆栈是空的话,就应该将其移除。
那进阶的问题这么处理呢?
这个问题确实有点难度。实现起来也比较麻烦,因为整个系统看起来应该像一个“翻转”系统。如果我从堆栈1中弹出一个元素,那么我们需要将堆栈2底部的元素压到堆栈1的顶端。堆栈3的元素要到堆栈2....
注:你可能会不同意我的说法。认为实现这个函数不需要“翻转”整个堆栈。系统中的每个堆栈并不需要都是满栈的,这样的话也可以省下很多的时间复杂度,特别是在堆栈非常大的时候。但是如果假设除了最后一个堆栈之外,所有的堆栈必须满栈的话,这样的方法就不行了。具体采用什么样的结构,你可以在面试时和面试官好好沟通然后决定。
3 4 In the classic problem of the Towers of Hanoi, you have 3 rods and N disks of different sizes which can slide onto any tower The puzzle starts with disks sorted in ascending order of size from top to bottom (e g , each disk sits on top of an
even larger one) You have the following constraints: (A) Only one disk can be moved at a time (B) A disk is slid off the top of one rod onto the next rod (C) A disk can only be placed on top of a larger disk Write a program to move the disks from the first
rod to the last using Stacks
3.4 经典的汉诺塔问题,有3根柱子,柱子上串有N个尺寸不同的碟子。汉诺塔问题的起始状态为,所有的碟子都从小到大的穿在柱子上(下面的碟子最大)。在满足下面三个限制:(A) 每次只能移动一个碟子;(B) 只有每根柱子顶端的碟子才能移动;(C)任何碟子只能放在比它大的碟子上。写一段程序(要求使用堆栈),将第一个根柱子上所有的碟子移动到移到最后一根柱子上。
3.4解答:
首先我们考虑解题的算法:将N个碟子从第一根柱子移到最后一根柱子。我们先从最简单的情况开始。如果只有一个碟子,那么直接将它移到最后的柱子。那两个碟子呢?
(1)先将第一个碟子从第一根柱子移到第二根
(2)将第二个碟子从第一根柱子上移动到第三根
(3)再将第二根柱子上的碟子移动到第三根上,完成!
那三个碟子呢?
(1)采用两个碟子移动的方法,讲上两个碟子移动到第二根柱子上
(2)将第三个碟子移动到第三根柱子
(3)在采用运来的方法将第二根柱子上的两个碟子移动到第三根柱子。
很明显采用递归算法就能解决本题:
3.5 Implement a MyQueue class which implements a queue using two stacks
3.5 用两个堆栈来实现一个队列
3.5解答:
堆栈和队列的最大区别在于:一个是先进后出,一个是后进先出。但是题目的要求使得peek和pop的动作恰好相反。那么我们就可以利用第二个堆栈完成入栈元素顺序的反转。(先所有的元素进堆栈S1,这样最先进栈的元素在栈底,最后的在栈顶;然后将S1中的元素依次弹出,并压入堆栈S2中。这样S2中先进的元素就在栈顶后进的就在栈底了。)
但是如果对队列和出队列的动作反复进行的话,我就要在S1和S2两个堆栈中反复的倒来倒去。其实有偷懒的方法。
当有元素要进入队列的时候,直接压如堆栈S1中,元素需要从队列中出列的话,检查S2中是否有元素,如果没有再采用之前的方法将S1中的元素“倒”入到S2中,如果S2中非空在直接弹出元素即为队列中出列的元素。这样的方法就免于在两个堆栈之间倒来倒去了:
3 6 Write a program to sort a stack in ascending order You should not make any assumptions about how the stack is implemented The following are the only functions that should be used to write this program: push | pop | peek | isEmpty
3.6 写一个程序将堆栈升序排序。该堆栈就是一个普通的堆栈,不能有其他假设。函数实现是只能调用函数push(),pop(),peek()和isEmpty这几个函数。
3.6解答:
再建一个堆栈,从原堆栈中弹出一个元素到新的堆栈中。然后再比较原堆栈栈顶元素和新堆栈栈顶大小。如果符合排序规则,再次入新堆栈。如果不符合,在弹出新堆栈中的元素逐个比较直到满足排序关系。这样类似插入排序的方法,之间复杂度为O(n^2)。
【IT笔试面试题整理】堆栈和队列的更多相关文章
- Java笔试面试题整理第六波(修正版)
转载至:http://blog.csdn.net/shakespeare001/article/details/51330745 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第四波
转载至:http://blog.csdn.net/shakespeare001/article/details/51274685 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第三波
转载至:http://blog.csdn.net/shakespeare001/article/details/51247785 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第二波
转载至:http://blog.csdn.net/shakespeare001/article/details/51200163 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第一波
转载至:http://blog.csdn.net/shakespeare001/article/details/51151650 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第八波
转载至:http://blog.csdn.net/shakespeare001/article/details/51388516 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第五波
转载至:http://blog.csdn.net/shakespeare001/article/details/51321498 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- C++笔试面试题整理
朋友给出的一些常见的C++面试题,特整理如下,后期遇到新的再更新. 面试题 列举并解释C++中的四种运算符转化,说明它们的不同点: static_cast: 在功能上基本上与C风格的类型转换一样强大, ...
- 【IT笔试面试题整理】给定一个数组a[N]构造数组b [N]
[来源]:腾讯2013实习生笔试 给定一个数组a[N],我们希望构造数组b [N],其中b[j]=a[0]*a[1]-a[N-1] / a[j])空间复杂度和O(n)的时间复杂度:除遍历计数器与a ...
随机推荐
- ESP-IDF3.0
发行版v3.0的文档可在http://esp-idf.readthedocs.io/en/v3.0/上找到. 这是自发布v3.0-rc1以来的更改列表. 如果从以前的稳定版本V2.1进行升级,请检查v ...
- hdu5016
题意:给定一个n个点的图,这个图是一棵树,然后有些点建立了集市.并且没有集市的地方去集市一定是去最近的,如果距离相同,那么则去标号最小的..现在你还能在建一个集市,问建完这个集市最多有多少个点来这里. ...
- C# 函数式编程及Monads.net库
函数式编程中,一切皆为函数,这个函数一般不是类级别的,其可以保存在变量中,可以当做参数或返回值,是函数级别的抽象和重用,将函数作为可重用的基本模块,就像面向对象中一切皆为对象,把所有事物抽象为类,面向 ...
- [ASE][Daily Scrum]11.11
各位1111快乐,不知道大家的卡上还剩多少钱啊~~~ TCP server目前遇到一点小瓶颈,不过server的两个人承诺说明天就可以搞定,给他们加油!~! 今天的plan~ View Shilin ...
- golang简单实现jwt验证(beego、xorm、jwt)
程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息. app.conf文件内容(可以用个beego直接读取里面的内容)写的是一个jwt的se ...
- NHibernate问题求大神解决!!!
这是我定义的实体类 对应的数据库表 映射文件 数据访问层写的是插入语句 错误: 捕捉到 NHibernate.Exceptions.GenericADOException HResult=-21462 ...
- 背水一战 Windows 10 (57) - 控件(集合类): ListViewBase - 增量加载, 分步绘制
[源码下载] 背水一战 Windows 10 (57) - 控件(集合类): ListViewBase - 增量加载, 分步绘制 作者:webabcd 介绍背水一战 Windows 10 之 控件(集 ...
- [学习笔记]BSGS
\(\%\%\% Fading\) 早就会了,我最近才理解,当时颓废太多忘学了 1.[SDOI2013]随机数生成器 当天正好在学数列,回来发现用必修五的知识就没了-- 不过特判好烦啊. \(Code ...
- Java几种单例模式的实现与利弊
饿汉式 提前new出来实例了,并不是在第一次调用get方法时才实例化,没有进行延迟加载 public class Singleton1 { private static Singleton1 inst ...
- C#6.0语言规范(九) 命名空间
C#程序使用命名空间进行组织.命名空间既可以用作程序的“内部”组织系统,也可以用作“外部”组织系统 - 一种呈现暴露给其他程序的程序元素的方式. 提供了使用指令(使用指令)以便于使用命名空间. 编译单 ...