关于数组的面试题总结(一)

来源:互联网 发布:帝国时代2日本武士数据 编辑:程序博客网 时间:2024/06/01 07:30

关于数组的面试题总结(一):

1.      二维数组中的查找

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。


2.      采用递归的方法求数组所有元素的和


3.      求数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。哎,这个题目居然WA了很多次,虽然看了剑指Offer,记得那个奇妙的计数方法,但是需要切记的是:找到可能的元素之后还需要再检查,因为给定的数组并不能保证一定有超过一半的数字出现。


4.      旋转数组(包括重复元素)的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。


5.      在旋转数组(不包含重复元素)中查找指定元素,返回位置


6.      在旋转数组(包含重复元素)中查找指定元素,返回是否存在


7.      调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。[九度]

下面是剑指Offer中介绍的方法,但是超时!


下面参考别人的方法AC了,但是不够漂亮!


8.      数组前半部分和后半部分分别有序(递增),采用O(1)的空间实现两部分的归并,这里暂不探究时间复杂度。

第一种方法,直观地对两段有序数组进行归并,left和right分别用来指向前半部分和后半部分我们正在考虑的元素,若left指向的小,则left直接后移即可,而若right指向的元素小,则需要互换left与right所指的之后,为了保证后半部分数组有序,需要将原left所指的值放在正确的位置。


第二种方法,有一点点技巧,因为上面的方法是将元素一个一个的调整到合适的位置,有时候可能后面部分有大片元素可以一起调整到合适的位置,如{7, 8, 9, 1, 2, 3,},我们只需要经过一次变换将1,2,3集体移到恰当的位置,数组就有序了。

具体做法,设数组为O, A1, A2, ..., As, B1, B2, ..., Bt; (前面的O表示已有序的部分,初始情况为空)

 我们还是需要left和right两个指针分别指向A和B部分的起始位置,当left指向的元素小时与上面一样,但当right所指向的元素小时,我们在B中沿着right向后找出所有比A1小的元素,不妨设B1 < B2 < B3 < ... < Bk < A1,接下来我们将B1...Bk这部分放到恰当的位置,就是把A1, A2, ..., As和 B1, B2, ..., Bk这两块交换,这是一个很典型的问题,可以通过三个反转操作实现。

原始数组: O, A1, A2, ..., As;  B1, B2, ..., Bk, Bk+1, ..., Bt

A部分反转:O, As, As-1, ..., A1;  B1, B2, ..., Bk, Bk+1, ..., Bt

B部分反转:O, As, As-1, ..., A1;  Bk, Bk-1, ..., B1, Bk+1, ..., Bt

AB部分反转:O, B1, B2, ..., Bk; A1, A2, ..., As,  Bk+1, ..., Bt


9.  采用O(n)的时间和 O(1)的空间复杂度,实现通过数组a计算数组b,其中 bi = a1*a2*...*an/ai,不能使用除法。


10.  求数组中子数组的连续最大乘积(最大连续子数组之和是很经典的动态规划,这里就不说了)

版本1:边界容易出错


版本2:不容易出错



0 0
原创粉丝点击