您的位置:首页 > 理论基础 > 数据结构算法

算法工程师能力评估

2016-09-04 20:16 204 查看
刚做了一套算法题(题目链接:算法工程师能力评估),总结一下。

1、对于以下程序,递归算法x(x(8))需要调用几次函数x(int n)?

class program
{
static void Main(string[] args)
{
int i;
i = x(x(8));
}
static int x(int n)
{
if (n <= 3)
return 1;
else
return x(n - 2) + x(n - 4) + 1;
}
}


9

12

18

24
分析:根据题意,易得x(3) = x(2) = x(1) = x(0) = 1

x(8) = x(6) +x(4) +1

       = x(4) + x(2) +1 + x(2) + x(0) +1 + 1 

       = x(2) + x(0) +1 + 1 + 1 +1 + 1 +1 + 1 

       = 9 

x(8) 这个就调用了9次函数x(int n),同理可得x(9)也是调用了9次函数x(int n),所以总共18次。

2、下列关于树的宽度优先搜索算法描述错误的是?

从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止

常采用先进后出的栈来实现算法

空间的复杂度为O(V+E),因为所有节点都必须被储存,其中V是节点的数量,E是边的数量

时间复杂度为O(V+E),因为必须寻找所有到可能节点的所有路径,其中V是节点的数量,E是边的数量

分析:广度优先算法使用的是队列的数据结构实现的。

3、在有序表(12,24,36,48,60,72,84)中二分查找关键字72时所需进行的关键字比较次数是多少?

1

2

3

4

分析:第一次二分查找取序列中间值48,比较72>48,第二次查找取48右侧的子序列60,72,84的中值72,比较72==72,返回,查找完成。

4、下面关于B-和B+树的叙述中,不正确的是

B-树和B+树都是平衡的多叉树

B-树和B+树都可用于文件的索引结构

B-树和B+树都能有效地支持顺序检索

B-树和B+树都能有效地支持随机检索

分析:B树的定义是这样的,一棵m阶的B树满足下列条件:(1)每个结点至多有m棵子树;(2)除根结点外,其他每个非叶子结点至少有m/2棵子树;(3)若根结点不是叶子结点,则至少有两棵子树;(4)所有叶结点在同一层上。B树的叶结点可以看成一种外部结点,不包含任何信息;(5)所有的非叶子结点中包含的信息数据为:(n,p0,k1,p1,k2,P2,…,kj-1,Pj-1)其中,ki为关键字,且满足kiki+1;pi为指向子树根结点的指针,并且Pi-1所指的子树中的所有结点的关键字均小于ki,Pj-1所指的子树中的所有结点的关键字均大于kj-1。B+树是应文件系统所需而出现的一种B树的变型树,其主要区别是一棵非叶子结点有n个子树就有n个关键字,这些关键字的作用是索引;所有的叶子结点包含了全部关键字的信息,以及指向这些关键字记录的指针,且叶子结点本身的关键字的大小自小而大顺序链接。从上述的特点中我们知道,这两种树都是平衡的多分树,它们都可以用于文件的索引结构,但B树只能支持随机检索,而B+树是有序的树,既能支持随机检索,又能支持顺序检索。选C。

5、具有3个结点的二叉树有几种形态?

4

5

6

7

分析:这是组合计数问题,最常见的catalan数(参考博客卡特兰数相关问题总结),C(n)=(1/(n+1))*((2*n)!/(n!*n!))

C(3) = (2*3)!/(3!*3!)/(3+1)=5。具体参考下图:



6、已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉树的后序遍历为多少?

DGEBFHAC

DGEBHFCA

DEGHBFCA

DEGBHACF

分析:



7、已知数据表A中每个元素距其最终位置不远,为节省时间排序,应采用什么方法排序?

堆排序

插入排序

快速排序

直接选择排序

分析:每个元素距其最终位置不远,直接插入排序不需要移动太多元素,适用于这种情况,效率高。

8、将N条长度均为M的有序链表进行合并,合并以后的链表也保持有序,时间复杂度为()?

O(N * M * logN)

O(N*M)

O(N)

O(M)

分析:

(1). 在每一个链表中取出第一个值,然后把它们放在一个大小为N的数组里,然后把这个数组当成heap建成小(大)根堆。此步骤的时间复杂度为O(N)

(2). 取出堆中的最小值(也是数组的第一个值), 然后把该最小值所处的链表的下一个值放在数组的第一个位置。如果链表中有一个已经为空(元素已经都被取出),则改变heap的大小。此步骤的时间复杂度为O(lg N).

(3). 不断的重复步骤二,直到所有的链表都为空。

建堆只建一次,复杂度为O(N);调整堆MN-1次,复杂度为(MN-1)*O(lg N)。所以为O(MN*lg N)

9、有2n个人排队进电影院,票价是50美分。在这2n个人当中,其中n个人只有50美分,另外n个人有1美元(纸票子)。愚蠢的电影院开始卖票时1分钱也没有。
问: 有多少种排队方法使得每当一个拥有1美元买票时,电影院都有50美分找钱?
注: 1美元=100美分,拥有1美元的人,拥有的是纸币,没法破成2个50美分。

(2n)!/[n!n!]

(2n)!/[n!(n+1)!]

(2n)!/[n!(n-1)!]

(2n + 1)!/[n!(n-1)!]

分析:这个是卡特兰数的经典应用。(参考博客卡特兰数相关问题总结)

10、T(n)
= 25T(n/5)+n^2的时间复杂度?

O(n^2*(lgn))

O(n^2)

O(lgn)

O(n*n*n)

分析:

T(n) = 25*T(n/5) + n^2

       = 25*( 25*T(n/25) + (n/5)2 ) + n^2 

       = 5^4*T(n/52) + 2*n^2 

       = 5^(2k)*T(n/5k) + k*n^2 

根据主方法,有T(n) = aT(n/b)+O(n^d), 则a=5^(2k), b=5k, d=2, a=b^d。

所以T(n)=O(n^d*(lgn))=O(n^2(lgn))。

11、连续整数之和为1000的共有几组?(m,n都为正整数)

3

4

5

8

分析:

连续整数之和m到n, 通项公式为S=(n+m)(m-n+1)/2,这里S=1000。得:

(n+m)(m-n+1) = 2000 = 2^4 * 5 ^3,可以看出这两个数必须满足一个奇数,一个偶数,这里取i=0,1,2,3,i为5的指数

(1): i=0,奇数=1,偶数=2000,n+m=2000, m-n+1=1,得m=n=1000(这个算吗?貌似答案算了)

(2):i=1,奇数=5,偶数=400,n+m=400, m-n+1=5,m=203,n=197

(3):i=2,奇数=25,偶数=80,n+m=80, m-n+1=25 ,m=53,n=27

(4):i=3,奇数=125,偶数=160,n+m=16, m-n+1=125 ,m=71,n=54

12、一个有序数列,序列中的每一个值都能够被2或者3或者5所整除,这个序列的初始值从1开始,但是1并不在这个数列中。求第1500个值是多少?

2040

2042

2045

2050

分析:2、3、5的最小公倍数是30。[ 1, 30]内符合条件的数有22个。如果能看出[ 31, 60]内也有22个符合条件的数,那问题就容易解决了。也就是说,这些数具有周期性,且周期为30。第1500个数是:1500/22=68
  1500%68=4。也就是说:第1500个数相当于经过了68个周期,然后再取下一个周期内的第4个数。一个周期内的前4个数:2,3,4,5。
故,结果为68*30=2040+5=2045。

另外一条思路:设x个数,x/2+x/3+x/5-x/6-x/10-x/15+x/30=1500解出来就行了。(此处的原理是根据集合的容斥定律:A∪B∪C
= A + B + C - A ∩ B - B ∩ C - A ∩ C + A ∩ B ∩ C)

13、写出a*(b-c*d)+e-f/g*(h+i*j-k)的逆波兰表达式。

a(b-c*d)*+e-(f/g(h+i*j-k)*)

a(b-(cd*))*+e-(fg/(h+ij*-k)*)

a(bcd*-)*+e-(fg/hij*+k-*)

abcd*-*e+fg/hij*+k-*-

分析:逆波兰表达式求值算法:

(1)、循环扫描语法单元的项目。

(2)、如果扫描的项目是操作数,则将其压入操作数堆栈,并扫描下一个项目。

(3)、如果扫描的项目是一个二元运算符,则对栈的顶上两个操作数执行该运算。

(4)、如果扫描的项目是一个一元运算符,则对栈的最顶上操作数执行该运算。

(5)、将运算结果重新压入堆栈。

(6)、重复步骤(2)-(5),堆栈中即为结果值。

14、下列关于线性表,二叉平衡树,哈希表存储数据的优劣描述错误的是?

哈希表是一个在时间和空间上做出权衡的经典例子。如果没有内存限制,那么可以直接将键作为数组的索引。那么所有的查找时间复杂度为O(1);

线性表实现相对比较简单

平衡二叉树的各项操作的时间复杂度为O(logn)

平衡二叉树的插入节点比较快
分析:哈希表是一个在时间和空间上做出权衡的经典例子。如果没有内存限制,那么可以直接将键作为数组的索引。那么所有的查找时间复杂度为O(1);如果没有时间限制,那么我们可以使用无序数组并进行顺序查找,这样只需要很少的内存。在平衡二叉树中插入结点要随时保证插入后整棵二叉树是平衡的,所以可能需要通过一次或多次树旋转来重新平衡这个树。答案选D。

15、下面程序的功能是输出数组的全排列,请填空。

void perm(int list[], int k, int m)
{
if (    )
{
copy(list,list+m,ostream_iterator<int>(cout," "));
cout<<endl;
return;
}
for (int i=k; i<=m; i++)
{
swap(&list[k],&list[i]);
(    );
swap(&list[k],&list[i]);
}
}


k!=m 和 perm(list,k+1,m)

k==m 和 perm(list,k+1,m)

k!=m 和 perm(list,k,m)

k==m 和 perm(list,k,m)

分析:参考博客全排列的一些总结。答案选B。

16、已知的一个无向图(边为正数)中顶点A,B的一条最短路P,如果把各个边的权重(即相邻两个顶点的距离)变为原来的2倍,那么在新图中,P仍然是A,B之间的最短路,以上说法是()

错误

正确

分析:如果将各条边的权值按从小到大排序的话,权值乘以2之后的排序不变,也就是权重的相对关系不变,p仍是最短路径。

17、如果一个堆栈的入栈序列是A,B,C,D,E,则堆栈的不可能输出顺序是()。

A、EDCBA   B、DECBA  C、DCEAB  D、ABCDE

分析:A 可行,ABCDE依次入栈,然后再依次出栈;
B 可行,A入栈,B入栈,C入栈,D入栈,D出栈,E入栈,E出栈,CBA依次出栈;
C 不可行,A入栈,B入栈,C入栈,D入栈,D出栈,C出栈,E入栈,E出栈,此时只能B先出栈,得不到AB;
D 可行,A入栈,A出栈,B入栈,B出栈,C入栈,C出栈,D入栈,D出栈,E入栈,E出栈。


18、若以{4,5,6,7,8}作为叶子结点的权值构造哈夫曼树,则其带权路径长度是()。

24

30

53

69

分析:树的带权路径长度(Weighted Path Length of Tree):定义为树中所有叶结点的带权路径长度之和。
结点的带权路径长度:结点到树根之间的路径长度与该结点上权的乘积。
构造哈夫曼树后,4,5的编码长度为3,6,7,8的编码长度为2,(4+5)*3+(6+7+8)*2=27+42=69。

19、用某种排序方法对关键字序列(25,84,21,47,15,27,68,35,20)进行排序,序列的变化情况采样如下:
20,15,21,25,47,27,68,35,84
15,20,21,25,35,27,47,68,84
15,20,21,25,27,35,47,68,84
请问采用的是以下哪种排序算法()

A、选择排序  B、希尔排序 C、归并排序
 D、快速排序

分析:首先第一步以25为基础,小于25的放在25的左边,大于25的放在25的右边

得到20,15,21,25,47,27,68,35,84

第二步在25的两边分别进行快速排序,左边以20为基数,右边以47为基数

得到15,20,21,25,35,27,47,68,84

第三步将,35,27这个子序列排序,得到

15,20,21,25,27,35,47,68,84

答案选择快速排序。

20、设某颗二叉树中有360个结点,则该二叉树的最小高度是?(包括根节点)

10

9

8

7

分析:同等结点数目,满二叉树高度最小,设二叉树的高度为n,则有:2^n-1>360,2^(n-1)
-1<360且n为正整数

求得n=9。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法与数据结构