首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

阿里巴巴笔试题选解

  • 25-03-02 17:02
  • 4582
  • 6343
blog.csdn.net

阿里巴巴笔试题选解

                                                               --9月22日,阿里巴巴北邮站

小题:

1、有三个结点,可以构成多少种二叉树形结构?

2、一副牌52张(去掉大小王),从中抽取两张牌,一红一黑的概率是多少?

编程题:

3、设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。情特别注意优化时间复杂度的常数。

4、已知三个升序整数数组a[l], b[m]和c[n]。请在三个数组中各找一个元素,是的组成的三元组距离最小。三元组的距离定义是:假设a[i]、b[j]和c[k]是一个三元组,那么距离为:

Distance = max(|a[ I ] – b[ j ]|, |a[ I ] – c[ k ]|, |b[ j ] – c[ k ]|)

请设计一个求最小三元组距离的最优算法,并分析时间复杂度。

5、在黑板上写下50个数字:1至50.在接下来的49轮操作中,每次做如下动作:选取两个黑板上的数字a和b,擦去,在黑板上写|b - a|。请问最后一次动作之后剩下数字可能是什么?为什么?

 

题解:(题解非官方,仅供参考,有错误的地方望指正!谢谢)

1、有三个结点的,可以构成多少个种二叉树形结构?

解:应该是5种;

 

2、一副牌52张(去掉大小王),从中抽取两张牌,一红一黑的概率是多少?

考察概率论知识

解法一: 52张牌从中抽两张,就是 C(2,52)种情况,一红一黑是C(1,26) * C(1,26)种

    P = [C(1,26) * C(1,26) ] / C(2,52) = 26 * 26 / (26 * 51) = 26/51

解法二: 全为黑或者全为红是C(2,26)种情况,由于是黑和红两种,所以要乘以2

    P = 1 - C(2,26) / C(2,52) - C(2,26) / C(2,52) = 1 - 2 * (26 * 25)/(51 * 52) = 1 - 25/51 = 26/51

3、设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。情特别注意优化时间复杂度的常数。

解:把数组两两一对分组,如果数组元素个数为奇数,就最后单独分一个,然后分别对每一组的两个数比较,把小的放在左边,大的放在右边,这样遍历下来,总共比较的次数是 N/2 次;在前面分组的基础上,那么可以得到结论,最小值一定在每一组的左边部分找,最大值一定在数组的右边部分找,最大值和最小值的查找分别需要比较N/2 次和N/2 次;这样就可以找到最大值和最小值了,比较的次数为

      N/2 * 3 = (3N)/2 次

如图会更加清晰:

代码实现:

  1. #include
  2. #include
  3. #define N 7
  4. int main()
  5. {
  6. int arr[N] = {4, 1, 5, 9, 9, 7, 10};
  7. int iter = 0;
  8. int cnt = 0;
  9. for(iter = 0; iter < N ; iter += 2)
  10. {
  11. if(++cnt && arr[iter] > arr[iter + 1] )
  12. {
  13. int temp = arr[iter];
  14. arr[iter] = arr[iter + 1];
  15. arr[iter + 1] = temp;
  16. }
  17. }
  18. int myMin = arr[0];
  19. for(iter = 2; iter < N ; iter += 2)
  20. {
  21. if(++cnt && arr[iter] < myMin)
  22. {
  23. myMin = arr[iter];
  24. }
  25. }
  26. int myMax = arr[1];
  27. for(iter = 3; iter < N; iter += 2)
  28. {
  29. if(++cnt && arr[iter] > myMax)
  30. {
  31. myMax = arr[iter];
  32. }
  33. }
  34. if(N % 2 != 0 && ++cnt && myMax < arr[N - 1]) myMax = arr[N - 1];
  35. printf("min is %d\n", myMin);
  36. printf("max is %d\n", myMax);
  37. printf("compare times is %d", cnt);
  38. return 0;
  39. }

   上面的算法比较次数基本上已经是最优了,但是有朋友提出这样的顾虑,在极端的情况下,每次都做交换,可能会导致程序开销很大,这样的顾虑是对的,其实在上面的算法的基础上,可以不做交换就能找到最大值和最小值。

第3题  改进的算法:

  依旧把数组两两一组分配,不做交换操作,设置一个最大值Max和最小值Min,依次和每一组的两个数据做比较,把较大的值给Max,较小的值给Min,遍历一次就能找到数组的最大值和最小值。

  示例:数组为{(4, 1) , (5, 9) , (9 ,7)  ,(10,2)},经过第一组比较得到Max = 4,Min = 1,其中比较了3次;,经过第二组比较得到Max = 9,Min = 1,其中比较了3次;……到最后Max = 10,Min = 1;比较次数是3 * N/2 = (3N)/2,比较次数没有改变!代码实现不难,就不贴了

4、已知三个升序整数数组a[l], b[m]和c[n]。请在三个数组中各找一个元素,是的组成的三元组距离最小。三元组的距离定义是:假设a[i]、b[j]和c[k]是一个三元组,那么距离为:

Distance = max(|a[ I ] – b[ j ]|, |a[ I ] – c[ k ]|, |b[ j ] – c[ k ]|)

请设计一个求最小三元组距离的最优算法,并分析时间复杂度。

解:这道题目有两个关键点:

  第一个关键点: max{|x1-x2|,|y1-y2|} =(|x1+y1-x2-y2|+|x1-y1-(x2-y2)|)/2   --公式(1)

  我们假设x1=a[ i ],x2=b[ j ],x3=c[ k ],则

Distance = max(|x1 – x2|, |x1 – x3|, |x2 – x3|) = max(   max(|x1 – x2|, |x1 – x3|) , |x2 – x3|)   --公式(2)

  根据公式(1),max(|x1 – x2|, |x1 – x3|) = 1/2 ( |2x1 – x2– x3| +  |x2 – x3|),带入公式(2),得到

Distance = max( 1/2 ( |2x1 – x2– x3| +  |x2 – x3|) , |x2 – x3| )  

      =1/2 * max(  |2x1 – x2– x3|  , |x2 – x3| ) + 1/2*|x2 – x3| //把相同部分1/2*|x2 – x3|分离出来

      =1/2 * max(  |2x1 – (x2 + x3)|  , |x2 – x3| ) + 1/2*|x2 – x3|   //把(x2 + x3)看成一个整体,使用公式(1)

      =1/2 * 1/2 *((|2x1 – 2x2| + |2x1 – 2x3|) + 1/2*|x2 – x3|

      =1/2 *|x1 – x2| + 1/2 * |x1 – x3| + 1/2*|x2 – x3|

      =1/2 *(|x1 – x2| + |x1 – x3| + |x2 – x3|)  //求出来了等价公式,完毕!

  第二个关键点:如何找到(|x1 – x2| + |x1 – x3| + |x2 – x3|) 的最小值,x1,x2,x3,分别是三个数组中的任意一个数,这一题,我只是做到了上面的推导,后面的算法设计是由csdn上的两个朋友想出来的方法,他们的CSDN的ID分别为 “云梦泽” 和 “ shuyechengying”.

算法思想是:

  用三个指针分别指向a,b,c中最小的数,计算一次他们最大距离的Distance ,然后在移动三个数中较小的数组指针,再计算一次,每次移动一个,直到其中一个数组结束为止,最慢(l+ m + n)次,复杂度为O(l+ m + n)

代码如下:

 

  1. #include
  2. #include
  3. #include
  4. #define l 3
  5. #define m 4
  6. #define n 6
  7. int Mymin(int a, int b, int c)
  8. {
  9. int Min = a < b ? a : b;
  10. Min = Min < c ? Min : c;
  11. return Min;
  12. }
  13. int Solvingviolence(int a[], int b[], int c[])
  14. {
  15. //暴力解法,大家都会,不用过多介绍了!
  16. int i = 0, j = 0, k = 0;
  17. int MinSum = (abs(a[i] - b[j]) + abs(a[i] - c[k]) + abs(b[j] - c[k])) / 2;
  18. // int store[3] = {0};
  19. int Sum = 0;
  20. for(i = 0; i < l; i++)
  21. {
  22. for(j = 0; j < m; j++)
  23. {
  24. for(k = 0; k < n; k++)
  25. {
  26. Sum = (abs(a[i] - b[j]) + abs(a[i] - c[k]) + abs(b[j] - c[k])) / 2;
  27. if(MinSum > Sum)
  28. {
  29. MinSum = Sum;
  30. // store[0] = i;
  31. // store[1] = j;
  32. // store[2] = k;
  33. }
  34. }
  35. }
  36. }
  37. // printf("the min is %d\n", minABC);
  38. // printf("the three number is %-3d%-3d%-3d\n", a[store[0]], b[store[1]], c[store[2]]);
  39. return MinSum;
  40. }
  41. int MinDistance(int a[], int b[], int c[])
  42. {
  43. int MinSum = 0; //最小的绝对值和
  44. int Sum = 0; //计算三个绝对值的和,与最小值做比较
  45. int MinOFabc = 0; // a[i] , b[j] ,c[k]的最小值
  46. int cnt = 0; //循环次数统计,最多是l + m + n次
  47. int i = 0, j = 0, k = 0; //a,b,c三个数组的下标索引
  48. MinSum = (abs(a[i] - b[j]) + abs(a[i] - c[k]) + abs(b[j] - c[k])) / 2;
  49. for(cnt = 0; cnt <= l + m + n; cnt++)
  50. {
  51. Sum = (abs(a[i] - b[j]) + abs(a[i] - c[k]) + abs(b[j] - c[k])) / 2;
  52. MinSum = MinSum < Sum ? MinSum : Sum;
  53. MinOFabc = Mymin(a[i] ,b[j] ,c[k]);//找到a[i] ,b[j] ,c[k]的最小值
  54. //判断哪个是最小值,做相应的索引移动
  55. if(MinOFabc == a[i])
  56. {
  57. if(++i >= l) break;
  58. }//a[i]最小,移动i
  59. if(MinOFabc == b[j])
  60. {
  61. if(++j >= m) break;
  62. }//b[j]最小,移动j
  63. if(MinOFabc == c[k])
  64. {
  65. if(++k >= n) break;
  66. }//c[k]最小,移动k
  67. }
  68. return MinSum;
  69. }
  70. int main(void)
  71. {
  72. int a[l] = {5, 6, 7};
  73. int b[m] = {13, 14, 15, 17};
  74. int c[n] = {19, 22, 24, 29, 32, 42};
  75. printf("\nBy violent solution ,the min is %d\n", Solvingviolence(a, b, c));
  76. printf("\nBy Optimal solution ,the min is %d\n", MinDistance(a, b, c));
  77. return 0;
  78. }

 5、这几天有点事,第5题还没仔细研究,要是解出来会第一时间更新博客!有求解方法的朋友欢迎评论!

题目部分摘取自july CSDN网站:http://iyenn.com/rec/1691595.html

 

注:1.本文版权归作者和CSDN所有,未经作者允许不得转载,侵权必究!

2.本博客与博客园上的博客为同一博客主:http://www.cnblogs.com/bestDavid/

注:本文转载自blog.csdn.net的大卫david的文章"http://blog.csdn.net/thebestdavid/article/details/11975809"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top