本篇介绍数组相关的基础题目。
题目一
用数组结构实现大小固定的队列和栈。(难度相当于一面的第一题)
实现栈
- index指向的是 新来的数要添加的位置。
- size 指的是固定的长度。
代码:
1 | # 用数组结构实现大小固定的队列和栈。(难度相当于一面的第一题) |
实现队列
循环利用这个数组
- start 变量指的是 拿取数据的位置。
- end 变量指的是 新来的数要添加的位置。
- size 指的已有元素的个数。
三个变量之间的关系:
- start与end没有关系。
- start与size有关:如果size不等于0,总把start位置处的数据取出来。
- end与size有关:如果size没超最大值,总把新来的数据放到end。
引入size的好处:
- start与end没有关系,所以不容易判断,何时追上了(满),何时为空,实现start 与 end 的解码。
- 有了size,加一个数,拿走一个数仅有size控制,简单很多。
实现:
1 | # 用数组结构实现大小固定的队列和栈。(难度相当于一面的第一题) |
题目二
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。(年年都考)
要求:
- pop、push、getMin操作的时间复杂度都是O(1)。
- 设计的栈类型可以使用现成的栈结构。
思路:
- 使用两个栈,data栈保存数据,min栈栈顶保存最小值,如果压入的数据比栈顶数据大,则将栈顶数据复制并压入;如果压入的数据比栈顶数据小,就把该数压入。
- 在弹出数据的时候同步弹出就行。
理解:
- data栈顶保存的是最新添加进入的数字,min栈的栈顶保存的是最新的这个数字与底下的数据进行比较后选出的较小值。这样pop后,不会对下面的数据产生影响。
实现:
1 | class ArrayStack(object): |
题目三
场景:图的深度优先遍历,通常使用栈来实现的,如果面试官让你使用队列呢?
- 实际上就是先用队列实现了栈,然后用这个栈来实现图的深度优先遍历。
队列实现栈
- 准备两个队列,一个队列中放入值
- pop时,先将 n-1 个值移动到另一个队列中,然后poll出最后这个值就可以。
1 | from queue import Queue |
栈实现队列
- 准备两个栈,push栈,pop栈
- push栈中存数据,pop栈中取数据
- 如果要pop数据,需要将push栈中所有数据都放入pop栈;
- 如果pop数据时,pop栈不为空,则push栈中的数据不能放入pop栈中
1 | from queue import LifoQueue |
题目四
猫狗队列
宠物、狗和猫的类如下:
1 | class Pet(object): |
实现一种猫狗队列的结构,要求如下:用户可以调用add方法将cat类或dog类的实例放入队列;用户可以调用pollAll方法,将队列中所有的实例按照进队列的先后顺序依次弹出;用户可以调用pollCat方法,将队列中cat类的实例按照进队列的先后顺序依次弹出;用户可以调用isEmpty方法,检查队列中是否有dog类的实例;用户可以调用isCatEmpty方法,检查队列中是否有cat类的实例。
题目五
转圈打印矩阵
宏观调度问题
给定一个整型矩阵matrix,请按照转圈的方式打印它。
例如:
1 | 1 -> 2 -> 3 -> 4 |
打印结果为:1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10
要求:额外空间复杂度为O(1)
代码:
1 | def spiral_order_print(m): |
题目六
矩阵旋转
宏观调度问题
扩展为一个N*N的正方形,顺时针旋转90度。要求:额外空间复杂度为O(1)
1 | 1 2 3 |
思路:
- 同上面的转圈,只要能把一圈做好,剩下就是一个缩小规模,重复调用的过程。
- 对于一圈中的所有元素,4个角要交换位置。
代码:
1 | def rotate(m): |
持续更新中!!!