淘宝研究院的面试题
来源:互联网 发布:ubuntu怎么下载qq 编辑:程序博客网 时间:2024/05/21 08:41
声明:本博文之所有权属于当年小丑,转载注明出处。没有当年小丑的书面许可,不得用于商业利益。
1. 有无序的实数列V[N],要求求里面大小相邻的实数的差的最大值,关键是要求线性空间和线性时间
2. 25匹赛马,5个跑道,也就是说每次有5匹马可以同时比赛。问最少比赛多少次可以知道跑得最快的5匹马
3. 有一个函数int getNum(),每运行一次可以从一个数组V[N]里面取出一个数,N未知,当数取完的时候,函数返回NULL。现在要求写一个函数int get(),这个函数运行一次可以从V[N]里随机取出一个数,而这个数必须是符合1/N平均分布的,也就是说V[N]里面任意一个数都有1/N的机会被取出,要求空间复杂度为O(1)
分析请见这里
第一题:参考了帖子的思想:鸽巢原理。用桶来做可以保证时间和空间都是线性的。我的实现中在hash表中添加两个字段,分别保存映射到同一个桶的元素中的最大值和最小值,也就是把输入放到桶中后的每个桶实际的上届和下界。这样做可以不必将输入的元素放到桶里去(我的实现中放进去了,这是多余的)。
产生数据:
/*file: data.c*/#include <stdio.h>#include <time.h>int main(){ FILE * filein, * fileout;int n,i; filein = freopen ("in.txt", "r", stdin); fileout = freopen ("outf.txt", "w", stdout);srand (time (NULL)); scanf ("%d", &n); printf ("%d\n",n);for (i=0; i<n; i++){ printf ("%d\t", rand()); if (9==i%10){ puts (""); }}puts ("");fclose (filein);fclose (fileout);return 0;}
/* file: max_neighbor_real_diff.c *//* compute the max differences of two neighbor elements in a reals sequence */#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <time.h>/* find the max difference between two negibour floats */float max_diff (float flt[], int n, float * f_max, float * f_min);int main(){ float * a; float f,f_max,f_min; int i; int n;#ifdef DEBUG1 FILE * filein = freopen ("outf.txt", "r", stdin); assert (NULL!=filein);#endif scanf ("%d", &n); assert (1<n); a = (float *) malloc (sizeof (float) * n); assert (NULL!=a); for (i=0; i<n; i++){ scanf ("%f", &a[i]); } puts ("array:\n"); for (i=0; i<n; i++){ printf ("%6.1f\t", a[i]); if (9==i%10){ puts (""); } } puts (""); f = max_diff (a, n, &f_max, &f_min); printf ("after calcluating:\nmax_diff = %6.1f\nf_max = %6.1f\nf_min = %6.1f\n",f, f_max, f_min); if (a){ free (a); }#ifdef DEBUG1 fclose (filein);#endif return 0;}float max_diff (float flt[], int n, float * f_max, float * f_min){ float left_max, right_min, tmp_diff, max_dif; float max,min; float avg_diff; int * nat; int * bucket; int bucket_num; int i; struct hash_item_node{ float f; struct hash_item_node * next_node; }; struct hash_item_node * hash_node_p; struct hash_item_node * hash_node_q; struct hash_table_item{ float fmax; /* maximal element */ float fmin; /* minimal element */ struct hash_item_node * next_item; }; struct hash_table_item * hash_table; assert (1<n); /* find the maximal and minimal elements */ for (max = min = flt[0],i=1; i<n; i++){ if (max < flt[i]){ max = flt[i]; } if (min > flt[i]){ min = flt[i]; } } /* average difference of all the elements */ avg_diff = (max - min)/(n-1); /* hash table index: mapping each element to a natural numbers */ nat = (int *) malloc (sizeof (int) * n); assert (NULL != nat); for (i=0; i<n; i++){ nat[i] = (int)((flt[i] - min)/avg_diff); } /* create a hash table */ hash_table = (struct hash_table_item *) malloc (sizeof (struct hash_table_item) * n); assert (NULL!=hash_table); /* initialize the hash table */ for (i=0; i<n; i++){ hash_table[i].fmax = 0.0f; hash_table[i].fmin = 0.0f; hash_table[i].next_item = NULL; } /* put the array into the hash table */ for (i=0; i<n; i++){ /* create a new hash_item_node with value flt[i] */ hash_node_p = (struct hash_item_node *) malloc (sizeof (struct hash_item_node)); assert (NULL!=hash_node_p); hash_node_p->f = flt[i]; hash_node_p->next_node = NULL; /* insert the newly created node into hash table */ if (NULL==hash_table[nat[i]].next_item){ hash_table[nat[i]].next_item = hash_node_p; hash_table[nat[i]].fmax = hash_node_p->f; /* recored the maximal element */ hash_table[nat[i]].fmin = hash_node_p->f; /* recored the minimal element */} else{ if (hash_table[nat[i]].fmax < hash_node_p->f){ hash_table[nat[i]].fmax = hash_node_p->f; /* recored the maximal element */} if (hash_table[nat[i]].fmin > hash_node_p->f){ hash_table[nat[i]].fmin = hash_node_p->f; /* recored the minimal element */} hash_node_p->next_node = hash_table[nat[i]].next_item; hash_table[nat[i]].next_item = hash_node_p;} hash_node_p = NULL; } /* recored the nonempty hash table item */ bucket_num = 0; bucket = (int *) malloc (sizeof (int)* n); assert (NULL!=bucket); for (i=0; i<n; i++){ if (NULL!=hash_table[i].next_item){ bucket[bucket_num++]=i;} } /* scan the hash table and computing the maximal neighbor difference */ max_dif = 0.0f; for (i=0; i<bucket_num-1; i++){ tmp_diff = hash_table[bucket[i+1]].fmin - hash_table[bucket[i]].fmax; if (max_dif < tmp_diff){ max_dif = tmp_diff; left_max = hash_table[bucket[i]].fmax; right_min = hash_table[bucket[i+1]].fmin;} } /* memory free */ for (i=0; i<bucket_num; i++){ hash_node_p = hash_table[bucket[i]].next_item; while (NULL!=hash_node_p){ hash_node_q = hash_node_p->next_node; free (hash_node_p); hash_node_p = hash_node_q; } } if (hash_table){ free (hash_table); } if (nat){ free (nat); } if (bucket){ free (bucket); } /* return */ *f_max = right_min; *f_min = left_max; return max_dif;}
删去冗余:
float max_diff (float flt[], int n, float * f_max, float * f_min){ float left_max, right_min, tmp_diff, max_dif; float max,min; float avg_diff; int * nat; int * bucket; int bucket_num; int i; struct hash_table_item{ float fmax; /* maximal element */ float fmin; /* minimal element */ int empty; /* 1 indicate empty, 0 indicate NOT empty */ }; struct hash_table_item * hash_table; assert (1<n); /* find the maximal and minimal elements */ for (max = min = flt[0],i=1; i<n; i++){ if (max < flt[i]){ max = flt[i]; } if (min > flt[i]){ min = flt[i]; } } /* average difference of all the elements */ avg_diff = (max - min)/(n-1); /* hash table index: mapping each element to a natural numbers */ nat = (int *) malloc (sizeof (int) * n); assert (NULL != nat); for (i=0; i<n; i++){ nat[i] = (int)((flt[i] - min)/avg_diff); } /* create a hash table */ hash_table = (struct hash_table_item *) malloc (sizeof (struct hash_table_item) * n); assert (NULL!=hash_table); /* initialize the hash table */ for (i=0; i<n; i++){ hash_table[i].fmax = 0.0f; hash_table[i].fmin = 0.0f; hash_table[i].empty = 1; } /* put the array into the hash table */ for (i=0; i<n; i++){ /* use the reals to update each hash item */ if (1==hash_table[nat[i]].empty){ hash_table[nat[i]].fmax = flt[i]; /* recored the maximal element */ hash_table[nat[i]].fmin = flt[i]; /* recored the minimal element */ hash_table[nat[i]].empty = 0;} else{ if (hash_table[nat[i]].fmax < flt[i]){ hash_table[nat[i]].fmax = flt[i]; /* recored the maximal element */} if (hash_table[nat[i]].fmin > flt[i]){ hash_table[nat[i]].fmin = flt[i]; /* recored the minimal element */}} } bucket_num = 0; bucket = (int *) malloc (sizeof (int)* n); assert (NULL!=bucket); for (i=0; i<n; i++){ if (!hash_table[i].empty){ bucket[bucket_num++]=i;} } /* scan the hash table and computing the maximal neighbor difference */ max_dif = 0.0f; for (i=0; i<bucket_num-1; i++){ tmp_diff = hash_table[bucket[i+1]].fmin - hash_table[bucket[i]].fmax; if (max_dif < tmp_diff){ max_dif = tmp_diff; left_max = hash_table[bucket[i]].fmax; right_min = hash_table[bucket[i+1]].fmin;} } /* memory free */ if (hash_table){ free (hash_table); } if (nat){ free (nat); } if (bucket){ free (bucket); } /* return */ *f_max = right_min; *f_min = left_max; return max_dif;}
array:19265.0 834.028849.010302.0 379.014280.018890.017461.05647.09698.019511.026108.01994.021693.06082.020042.029786.03037.013359.02781.0 854.08719.029798.023822.0 639.014495.05332.028328.05958.014028.06414.018682.010638.06521.011447.016939.027570.027429.02981.021710.09162.030749.013631.05558.06698.04848.028457.015372.020780.032036.023332.028574.027184.018471.09263.020858.023520.017032.01778.029372.023993.017767.014685.011684.011463.030251.030093.05356.03503.020595.011247.027992.012275.03150.08359.025998.022130.013486.030771.0 40.026926.0 538.030539.025608.021586.019876.031244.01771.022644.012315.026198.026177.012311.08577.07539.016957.011892.011455.012537.03880.0after calcluating:max_diff = 1615.0f_max = 25608.0f_min = 23993.0
结果和如下的排序之后比较的结果一样:
/* file: max_real_diff_by_qsort.c */#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <time.h>/* find the max difference between two negibour floats */float max_diff (float flt[], int n, float * f_max, float * f_min);int main(){ float * a; float f,f_max,f_min; int i; int n;#ifdef DEBUG1 FILE * filein = freopen ("outf.txt", "r", stdin); assert (NULL!=filein);#endif scanf ("%d", &n); assert (1<n); a = (float *) malloc (sizeof (float) * n); assert (NULL!=a); for (i=0; i<n; i++){ scanf ("%f", &a[i]); } puts ("array:\n"); for (i=0; i<n; i++){ printf ("%6.1f\t", a[i]); if (9==i%10){ puts (""); } } puts (""); int f_cmp (const void * a, const void * b); qsort (a, n, sizeof (float), f_cmp); for (i=0; i<n-1; i++){ a[i] = a[i+1]-a[i]; } f = a[0]; for (i=1; i<n-1; i++){ if (f<a[i]){ f=a[i]; } } printf ("f = %6.1f\n",f); if (a){ free (a); }#ifdef DEBUG1 fclose (filein);#endif return 0;}int f_cmp (const void * a, const void * b){ if ( *(float *)a - *(float *)b > 1e-6){ return 1; } else if ( *(float *)b - *(float *)a > 1e-6){ return -1; } else{ return 0; }}
第二题:8次可以找出跑的最快的五匹马。
初始化:25匹马随机均分为5组,每一组的组号用字母表示,同一组内的马用数字来编号,这些马被标记为
A1,A2,A3,A4,A5B1,B2,B3,B4,B5
C1,C2,C3,C4,C5
D1,D2,D3,D4,D5
E1,E2,E3,E4,E5
第一轮 ~ 第五轮:每一组马进行组内比赛,并根据比赛的平均速度进行排序,假设结果是
A1>A2>A3>A4>A5
B1>B2>B3>B4>B5
C1>C2>C3>C4>C5
D1>D2>D3>D4>D5
E1>E2>E3>E4>E5
第六轮:A1,B1,C1,D1,E1进行比赛,假设结果为:
A1>B1>C1>D1>E1
第七轮:A2,A3,B2,C2,D1进行比赛,比赛结果可以根据D1的名次分为三大类:假设结果为:
7.1 假设D1是第一名:意味着D1快于A2,B2,C2;那么
第八轮:D2,E1和第七轮的第一名(共3匹马)比赛,跑得最快的五匹马为:本次比赛的第一名和A1,B1,C1,D1;
7.2 假设D2是第二名:那么可以分三种情况讨论,
7.2.1 假如第一名是A2,那么跑得最快的五匹马是A1,A2,B1,C1,D1;
第八轮:无需比赛。
7.2.2 假如第一名是B2:
第八轮:D1和B3比赛,跑得最快的五匹马为:本次比赛的第一名和A1,B1,B2,C1;
7.2.3 假如第一名是C2:
第八轮:D1和C3比赛,跑得最快的五匹马为:本次比赛的第一名和A1,B1,C1,C2;
7.3 假设D3不是第一名,也不是第二名,那么根据第一名和第二名可能出现的结果,可以分为七类不同的情形:
注:---- 表示无需比赛。
综上所述,8次比赛就可以找出最快的5匹马。
第三题:结合第485楼的回答来进行分析。
据说这道题改编自微软的面试题。本质上等价于问这样一个问题:一个箱子里有N-1个蓝球和1个红球,每次抓取一个球。问题:第1次抓到红球的概率是多少?第k次抓到红球的概率是多少?第N次抓到红球的概率是多少?
答:第1次抓到红球的概率:P(1)=1/N
第k次抓到红球的概率:P(k)=1/N =(N-1)/N * (N-2)/(N-1) * ... * (N-k+1)/(N-k) * 1/(N-k+1)
第N次抓到红球的概率:P(N)=1/N=(N-1)/N * (N-2)/(N-1) * ... * 1/2 * 1
解决方案:
由于已经给定函数getNum ():每次返回数组的一个数,取完了数之后则返回NULL。先定义变量,通过循环调用getNum () 来确定元素的个数(数组的数据结构应该不会被改变)。
然后,构造一个随机函数int random ( int k),返回 0~(k-1) 之间的一个整数,我们假设产生0~(k-1)之间任意一个数的概率都是1/k。那么函数 int get () 可以这样写:
/* 数组V */int get (){ /* 确定元素个数 */ int i = 0; while (NULL != getNum ()){ i++; } static int n = i; /* 返回一个元素 */ return V[random (n)];}
以上的操作的概率是由随机函数来保证的,并且,我们假设数组V是对我们开放访问并且 int getNum () 函数不修改其值。随机函数 int random (int k) 返回的每一个整数值映射到了数组V的某个元素,从而保证每个元素被取到的概率是1/N。
- 淘宝研究院的面试题
- [原创]微软中国研究院面试题的思考......
- 微软亚洲研究院的一道面试题
- 思-中国移动通信研究院的面试题
- 淘宝的一道面试题
- 淘宝的一道面试题
- 微软中国研究院最新面试题
- 微软亚洲研究院面试题
- 微软亚洲研究院提供的面试题分析
- 一道淘宝校园面试题的思考
- 淘宝某部门的技术面试题
- 淘宝面试题
- 淘宝面试题
- 淘宝面试题cacheline
- 淘宝面试题
- 月薪5万,微软中国研究院面试题
- 北京研究院联想公司android面试题
- 一道淘宝校园面试题
- Windows下安装Redmine
- atom not found in symbolIndex(___divdi3)
- 执行多条SQL语句,执行数据库事务(可传入Sql参数)
- 系统签名apk
- 我的第一篇编程博客
- 淘宝研究院的面试题
- ORA-01555 快照过旧
- c语言读写文件fopen
- 三分搜索
- JS混淆还原,w3wp.exe占用CPU过高
- 最近程序小记事
- 今年暑假不AC
- 基于Visual C++之Windows核心编程代码分析(3)实现程序自动安装
- Cocos2d-x学习笔记(六)实例——多层布景