阿里笔试部分题目分析(2015实习生 C/C++研发)

来源:互联网 发布:电脑行为监控软件 编辑:程序博客网 时间:2024/04/29 16:20

1、 找出海量数据(N)中的最大值K(<10000)个数,最开的平均时间复杂度是(O(n*logk))
针对此类典型的TOP K问题,采取的对策往往是:hashmap + 堆。如下所示:
hash_map统计:先对这批海量数据预处理。具体方法是:维护一个Key为Query字串,Value为该Query出现次数的HashTable,即hash_map(Query,Value),每次读取一个Query,如果该字串不在Table中,那么加入该字串,并且将Value值设为1;如果该字串在Table中,那么将该字串的计数加一即可。最终我们在O(N)的时间复杂度内用Hash表完成了统计;
堆排序:第二步、借助堆这个数据结构,找出Top K,时间复杂度为N‘logK。即借助堆结构,我们可以在log量级的时间内查找和调整/移动。因此,维护一个K(该题目中是10)大小的小根堆,然后遍历300万的Query,分别和根元素进行对比。所以,我们最终的时间复杂度是:O(N) + N’ * O(logK),(N为1000万,N’为300万)。
别忘了这篇文章中所述的堆排序思路:“维护k个元素的最小堆,即用容量为k的最小堆存储最先遍历到的k个数,并假设它们即是最大的k个数,建堆费时O(k),并调整堆(费时O(logk))后,有k1>k2>…kmin(kmin设为小顶堆中最小元素)。继续遍历数列,每次遍历一个元素x,与堆顶元素比较,若x>kmin,则更新堆(x入堆,用时logk),否则不更新堆。这样下来,总费时O(k*logk+(n-k)*logk)=O(n*logk)。此方法得益于在堆中,查找等各项操作时间复杂度均为logk。”
参考:http://blog.csdn.net/v_july_v/article/details/7382693
2、 容错技术:
http://blog.csdn.net/u012896140/article/details/44903777
3、 有如下函数作用是:(将num的i位至0位(含)清零)

int func(int num,int i){int tmp = ~(1<<(i+1)-1)return num&tmp;}

这个稍微动笔算一下立马就出来了 1<<(i+1) 比如i为3 左移后得到1000(2进制)
1000 – 1 = 0111 取反后得到 1000; 和num按位与将将num的i位至0位(含)清零。
5、二叉树节点的先跟序列,中根序列,后根序列中,所有叶子节点的先后顺序:(完全相同)
假设m、l、r分别是根、左、右叶子,那么前序中序以及后序输出如下:
前序:mlr
中序:lmr
后序:lrm
所以叶子节点l和r的相对次序是不变的。
6、下面的代码在64位linux系统编译执行,输出的结果是:

 #include<stdint.h> #include<stdio.h> void print_size(int32_t array[10]){    printf(“%d\n”,sizeof(array));}int main(){    int32_t myArray[10];    printf(“%d”,sizeof(myArray));    print_size(myArray);}

答案是 40, 8;
解释一下:在64位的系统里指针所占的大小为8个字节;32位的系统里指针所占的空间为4个字节;寻址范围是2^32 = 4G 而64位寻址范围是 2^64(无穷大);
7、以下程序输出是:

#include "iostream"using namespace std;int main(){    const int a = 10;    int * p = (int*)(&a);    *p = 20;    cout << a <<"\t"<<&a<< endl;    cout << *p <<"\t"<< p   <<endl;    getchar();}

这个题目我也是做错了, 原因是把c++和C弄混了, 如果是在c里面是编译警告的,
但是在c++里面却可以正确输出。原因是c++对const的处理,把const修饰的变量,固话到编译器的符号表里面了,作为一个常量了。无论如何都不会被修改 。为什么*p = 20;
因为他是指向到变量a的地址,把20存到里面了。
8、已经某个哈希表的n个关键字具有相同的哈希值,如果使用二次探测再散列法将这n个关键字存入哈希表,至少需要进行 n(n+1)/2 次探测;
9、将整数序列(7,2,4,6,3,1,5)所系顺序构建一课二叉排序树,之后将整数8按照二叉排序树规则插入树a中,请问插入之后的树a中序遍历结果。(1,2,3,4,5,6,7,8)
这就是考察二叉排序树的性质:二叉排序树(Binary Sort Tree)或者是一棵空树;或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;

                    7                  /   \                 2     8               /   \             1      4                  /    \               3        5                            \                             6

9、在0~999999之间的所有数字中,任何一位都不包括数字3的数字的总数为
9+8*9+8*9*9+8*9*9*9+8*9*9*9*9+8*9*9*9*9*9哈哈直接算你肯定跪就算你用计算器
把上面的式子合并同类项你就可以找出规律 9^6 = 531441
10、某团队有6位开发同学,需要参加5个项目,每位同学需要恰好参加1个项目,那么总共有3600不同的分配方法
排列组合:首先在6个同学中随机选出一个用于插队,剩余的5个同学分配到5项工作那么就是5!= 120,最后把那个一个同学再插入到5项任务中一共有6*120*5 = 3600
11、考察STL的知识点:ps这个感觉是(第二个和第四个都不对啊)题目有点问题
(1) STL容器是线程不安全的,正确,在这片博客里面有提到
http://blog.csdn.net/u012896140/article/details/40541309
(2)当容量不够的时候,vector内部内存的扩展方式不是翻倍;是指数的增长方式;
http://blog.csdn.net/jmy5945hh/article/details/39160763
(3)string中可以存储多个’\0’字符,正确;
很多人不理解,为什么我输出不出来呢,输出不出来因为cout遇到’\0’停止,但是确实存储到里面了,可以自己写一个字符串调试 看一下;
(4)bitset也是一个stl容器;怎么常见 但是确实是!
(5)stack是用deque实现的;正确
(6)STL中的sort可能是是不稳定的;正确
STL的sort()算法,数据量大时采用Quick Sort,分段递归排序,一旦分段后的数据量小于某个门槛,为避免Quick Sort的递归调用带来过大的额外负荷,就改用Insertion Sort。如果递归层次过深,还会改用Heap Sort。
12、某处理器有64个核心,他们可以并行运行,且可以无竞争的访问一个存储器,任意一个核心对存储器中两个数据进行求和并将结果存入存储器中需要时间t,现在有一个长度为32的数组,我们使用这个处理器求出数组中所有元素的总和,请问最少需要5t的时间
解析:32 == 2^5 t 每求一次之后都是前一次的一半。
13、设定数列{an}的前n项和为Sn,现在已知次数列满足an+Sn=10-7/2^n,求an的通项公式:
(3.5n+3)/2^n
解析:这道题技巧性的,把n = 1带进去求出n=13/4;然后,带入到下面答案中的接过去验证,发现只有这个是对的。

0 0
原创粉丝点击