创新工场笔试题

原文地址:http://blog.csdn.net/thebestdavid/article/details/11937355

1.输入一个整型无序数组,用堆排序的方法是数组有序

2.求一个正整数的开方,要求不能使用库函数sqrt,结果精度在0.01即可

3.给定一个矩阵int matrixA[m][n],每行没列都是增序的,实现一个算法寻找矩阵中的某个元素element

下面做出我的题解,能力有限,望见谅!

第一题:堆排序

  考的排序算法中的堆排序,这里稍微讲一下堆排序的算法:

  二叉树:

  基本概念:

  大根堆:  就是说父节点要比左右孩子都要大。

  小根堆:  就是说父节点要比左右孩子都要小。

  算法:

  1、从最后一个父结点开始,从后往前遍历树的所有二叉树的父节点,构造大顶堆;

  2、整个数都是大顶堆,那么树的根节点肯定是数组中的最大值,将其与最后一个元素交换swap,这时可能会破坏大顶堆,需要重新构建大顶堆,然后再取树的根节点与最后一个点交换,依次类推……

代码如下:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. void Heapadjust(int *arr, int parent, int cnt)  
  4. {  
  5.     int child;  
  6.     int ValParent;  
  7.     for(ValParent = arr[parent]; 2 * parent + 1 < cnt; parent = child)  
  8.     {  
  9.         child = 2 * parent + 1; //父节点的左子节点  
  10.         //右子节点存在且大于左子节点,则child+1  
  11.         if(child + 1 < cnt && arr[child] < arr[child + 1])  
  12.         {  
  13.             child++;  
  14.         }  
  15.         //若子节点大于根节点,则把子节点的值赋给根节点,否则跳出循环;跳出循环的原因是:  
  16.         //既然是从最后一个父节点开始往前构大根堆,如果父节点满足大根堆,那其子节点也满足大根堆  
  17.         if(arr[child] > arr[parent])  
  18.         {  
  19.             arr[parent] = arr[child];  
  20.         }  
  21.         else  
  22.         {  
  23.             break;  
  24.         }  
  25.         //没有跳出循环说明,父节点与子节点值交换了,那有可能会导致大根堆被破坏,所以要检查子节点  
  26.         //是否还是大根堆  
  27.         arr[child] = ValParent;  
  28.     }  
  29.   
  30. }  
  31. void Swap(int *a, int *b)  
  32. {  
  33.     int temp = *a;  
  34.     *a = *b;  
  35.     *b = temp;  
  36. }  
  37. void HeapSort(int *arr, int cnt)  
  38. {  
  39.     int iter = 0;  
  40.     //初始化大根堆,根据大根堆的特征,可以减少判断的次数  
  41.     for(iter = cnt / 2 - 1; iter >= 0; iter--)  
  42.     {  
  43.         Heapadjust(arr, iter, cnt);  
  44.     }  
  45.   
  46.     //大根堆的第一个数是最大的,将它与数组最后一个数作交换,每次交换都前移数组的尾数索引  
  47.     //交换过程中可能会导致大根堆遭破坏,所以要调用Heapadjust(arr, 0 , iter)构建大根堆  
  48.     //由于前面已经初始化大根堆,所以已经具备大根堆的特征,不需要再一个一个父节点的慢慢构建  
  49.     //只需要将Heapadjust的第二个参数设置为0,即大根堆的第一个父节点即可  
  50.     for(iter = cnt - 1; iter >= 0; iter--)  
  51.     {  
  52.         Swap(&arr[0], &arr[iter]);  
  53.         Heapadjust(arr, 0 , iter);  
  54.     }  
  55. }  
  56.   
  57. int main(void)  
  58. {  
  59.     int arr[] = {3, 2, 1, 4, 5 ,7 ,6, 12, 34, 34 ,56};  
  60.     int len = 11;  
  61.     HeapSort(arr, len);  
  62.     int i = 0;  
  63.     for( i = 0; i < len; i++)  
  64.     {  
  65.         printf("%4d",arr[i]);  
  66.     }  
  67.     return 0;  
  68. }  


第二题:二分法

  直接使用二分法即可解答问题,但是题目中所说的是正整数的开方,我觉得完全可以扩展到浮点型的开方,浮点型开方需要注意一点问题,就是大于1和小于1的情况不一样,比如0.9的平方是0.81,而我们是从0到0.81取二分的,显然肯定找不到0.9这个数,所以要稍作处理。

[cpp]  view plain copy
  1. /* 
  2.    分治法求平方根 
  3. */  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #define EPSION 0.000001  
  7. double MySqrt(double des)  
  8. {  
  9.     double low = EPSION;  
  10.     double high = EPSION;  
  11.     double mid = 0.0;  
  12.     double sqr = 0.0;  
  13.     high = des > 1.0 ? des : des + 1.0;  
  14.     do  
  15.     {  
  16.         mid = (low + high) / 2.0;  
  17.         sqr = mid * mid;  
  18.         if(sqr > des)  
  19.         {  
  20.             high = mid;  
  21.         }  
  22.         else  
  23.         {  
  24.             low = mid;  
  25.         }  
  26.     }while((sqr - des) < -EPSION || (sqr - des) > EPSION);  
  27.     return mid;  
  28. }  
  29. int main(void)  
  30. {  
  31.     double num = 0.0;  
  32.     do  
  33.     {  
  34.         printf("The number :");  
  35.         scanf("%lf", &num);  
  36.         if(num < 0)  
  37.         {  
  38.             printf("input error! Please input again!\n");  
  39.         }  
  40.     }while(num < 0);  
  41.     printf("Its sqrt is %.4lf\n", MySqrt(num));  
  42.     return 0;  
  43. }  


第三题:杨氏矩阵查找

  矩阵为MatrixA[m][n],要找的数字为element,从第一行的最后一列的数MatrixA[0][n - 1]开始查找,element比MatrixA[0][n - 1]小则向左查找,否则向下查找,直到找到该数时退出。图示如下:(可能就会有多个element,只需找到其中一个返回是否存在即可)

 

 

相应的代码:

[cpp]  view plain copy
  1. /* 
  2.     杨氏矩阵:查找 
  3. */  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #define M 4  
  7. #define N 4  
  8. int FindElement(int MatrixA[M][N], int element)  
  9. {  
  10.     int i = 0, j = N - 1;  
  11.     while(1)  
  12.     {  
  13.         while(MatrixA[i][j] >= element)  
  14.         {  
  15.             if(MatrixA[i][j] == element) return 1;  
  16.             j--;  
  17.             if(j < 0) return 0;  
  18.         }  
  19.         while(MatrixA[i][j] <= element)  
  20.         {  
  21.             if(MatrixA[i][j] == element) return 1;  
  22.             i++;  
  23.             if(i >= M) return 0;  
  24.         }  
  25.     }  
  26. }  
  27. int main(void)  
  28. {  
  29.     int MatrixA[M][N] = {{1, 3, 4, 8},  
  30.                          {3, 5, 6, 9},  
  31.                          {6, 7, 10, 11},  
  32.                          {7, 8, 12,15},  
  33.                         };  
  34.   
  35.     int i = 0;  
  36.     for(i = 1; i <= 15; i++)  
  37.     {  
  38.         printf("element: %-3d", i);  
  39.         switch(FindElement(MatrixA, i))  
  40.         {  
  41.             case 0: printf("don't exist!\n"); break;  
  42.             case 1: printf(" exist!\n"); break;  
  43.             defaultbreak;  
  44.         }  
  45.     }  
  46.     return 0;  
  47. }  
此题目摘取自july CSDN网站:http://blog.csdn.net/v_july_v/article/details/11921021
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值