免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 无风之谷
打印 上一主题 下一主题

这样的面试题,你会吗?(有奖) [复制链接]

论坛徽章:
0
71 [报告]
发表于 2011-12-07 12:40 |只看该作者
学习学习。。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
72 [报告]
发表于 2011-12-07 13:39 |只看该作者
本帖最后由 koolcoy 于 2011-12-07 13:45 编辑

1. 用stl二分查找
2. 青蛙1,通过递推公式计算,也可以用F数列的计算公式直接算;
青蛙2,f(n) = f(n - 1) + f(n - 2) + .. + f(1) + 1 最终结果就是f(n) = 2^(n - 1)

  1. #include <algorithm>

  2. bool f1_search(int** array, int needle, int rowCount, int columnCount) {
  3.         for (int i = 0; i < rowCount; ++i) {
  4.                 if (array[i][0] > needle) {
  5.                         return false;
  6.                 }
  7.                 int* x = std::lower_bound(array[i], array[i] + columnCount, needle);
  8.                 if (x != array[i] + columnCount && *x == needle) {
  9.                         return true;
  10.                 }
  11.         }
  12.         return false;
  13. }

  14. int f2_frog1(int n) {
  15.         int array[n + 1];
  16.         array[0] = 0;
  17.         array[1] = 1;
  18.         array[2] = 2;
  19.         for (int i = 3; i <= n; ++i) {
  20.                 array[i] = array[i - 1] + array[i - 2];
  21.         }
  22.         return n > 0 ? array[n] : 0;
  23. }

  24. int f2_frog2(int n) {
  25.         return (n > 0) ? (1 << (n - 1)) : 0;
  26. }
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
73 [报告]
发表于 2011-12-07 14:52 |只看该作者
明白了,
对于第一个问题,
如果整体
如果设整体的数据为n个的话
这个问题
只有平方根级别的时间复杂度算法,对数级别应该是不存在的
大致想出了证明方法

论坛徽章:
0
74 [报告]
发表于 2011-12-07 22:31 |只看该作者
回复 72# cjaizss


    求思路!!

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
75 [报告]
发表于 2011-12-08 09:02 |只看该作者
回复  cjaizss


    求思路!!
hbmhalley 发表于 2011-12-07 22:31



    我的证明思路就是用区域割图,直到割出至多常数个线型.但这只是一个思路,还没成为现实

论坛徽章:
1
技术图书徽章
日期:2013-09-17 09:11:51
76 [报告]
发表于 2011-12-08 17:52 |只看该作者
回复 1# 无风之谷


    个人觉得两道题都是一种常见的算法题。都可以用递归的方法实现:
   
   第一题是二维数组中查找特定值的问题。由于整个二维数组是有序的。所以就可以直接用简化的方法来查找。  
   下面是自己设计的一个递归的实现:
  1. /*
  2. 1,二维数组中的查找
  3. 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
  4. 例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true;如果查找数字4,由于数组不含有该数字,则返回false。

  5. 1   2   3   5   7
  6. 3   6   8   9   12
  7. 5   7   11  14  17
  8. 7   8   12  16  20
  9. 8   9   16  19  22

  10. 分析,查找出这个二维数组a[x][y]的第一行中第N个元素开始比要查找的数字大,
  11.       查找出这个二维数组的第一列中第M个元素开始比要查找的数字大,然后以N和M为下标找出对角线上的数,如果比要找的数大,则开始递归
  12.           递归的规则是:分别把行和列减去1进行递归,递归的退出条件是其中行或列为小于1.
  13. */

  14. #include <stdio.h>

  15. #define PAL_TRUE      1
  16. #define PAL_FALSE     0

  17. unsigned int findNumber (int a[][5], int line, int row, int numb)
  18. {
  19.   int i, j;
  20.   int line_index, row_index;
  21.   int is_find;

  22.   is_find = PAL_FALSE;
  23.   
  24.   if (a == NULL)
  25.     {
  26.           return PAL_FALSE;
  27.         }
  28.        
  29.   if (line == 0 || row == 0)
  30.     {
  31.           return PAL_FALSE;
  32.         }
  33.    
  34.   
  35.   for (i = 0; i < line; i++)
  36.     {
  37.           if (a[0][i] == numb)
  38.             {
  39.                   printf("\n a[0][%d] = %d", i, numb);
  40.                   return PAL_TRUE;
  41.                 }   
  42.       else if (a[0][i] > numb)
  43.             {
  44.                   line_index = i - 1;
  45.                   break;
  46.                 }
  47.         }
  48.   
  49.   if (i == line)
  50.     {
  51.           line_index = line;
  52.         }
  53.        
  54.   for (j = 0; j < row; j++)
  55.     {
  56.           if (a[j][0] == numb)
  57.             {
  58.                   printf("\n a[%d][0] = %d", j, numb);
  59.                   return PAL_TRUE;
  60.                 }
  61.           else if (a[j][0] > numb)
  62.             {
  63.                   row_index = j - 1;
  64.                   break;
  65.                 }
  66.         }
  67.   
  68.   if (j == row)
  69.     {
  70.           row_index = row;
  71.         }
  72.        
  73.   if (a[row_index][line_index] == numb)
  74.     {
  75.           printf("\n a[%d][%d] = %d", row_index, line_index, numb);
  76.           return PAL_TRUE;
  77.         }
  78.    

  79.   if (findNumber (a, line_index - 1, row_index, numb) == PAL_TRUE)
  80.     return PAL_TRUE;

  81.   if (findNumber (a, line_index, row_index - 1, numb) == PAL_TRUE)       
  82.     return PAL_TRUE;
  83.   
  84.   return PAL_FALSE;  
  85. }

  86. int main (void)
  87. {
  88.   int a[4][5] = {{1,2,3,5,100},{3,6,8,9,90},{5,7,11,14,80},{7,8,12,16,60}};
  89.   
  90.   int if_find1, if_find2, if_find3;
  91.   
  92.   if_find1 = findNumber (a, 5, 4, 16);
  93.   printf ("\n %s the number %d", if_find1 ? "find" : "not find", 16);

  94.   if_find2 = findNumber (a, 5, 4, 5);
  95.   printf ("\n %s the number %d", if_find2 ? "find" : "not find", 5);
  96.   
  97.   if_find3 = findNumber (a, 5, 4, 7);
  98.   printf ("\n %s the number %d", if_find3 ? "find" : "not find", 7);

  99.   return 0;  
  100. }
复制代码
第二题:
第一种情况可以先枚举一下,应该是费波那西数列 f(1)=1, f(2)=2. f(n)= f(n-1)+ f(n-2).   递归即可求得;
第二种情况应该是背包算法原理的一个另外一种延伸。题目可以理解为1到N里面的整数有几种组合相加可以得到n. 这里可以认为从1到N里的数组合要相加得到N,那么每一个数都有两种可能,一种是参与相加,一种是不参与相加。
           这样定义一个N个元素的数组a[N],如果1参与,则a[1] = 1;1不参与则a[1] = 0;  依次类推,定义一个全局变量,用递归的方法即可计算出所有的组合数。

隔了四五天没有逛论坛了,今天看到,不知道这样理解正不正确? 望老师纠正

论坛徽章:
0
77 [报告]
发表于 2011-12-11 00:09 |只看该作者
本帖最后由 jjboy110 于 2011-12-11 00:53 编辑

帖子怎么这么难写??

  1. 第一题:
  2. 我只说思路,程序就不写了呵呵
  3. 将该数与矩阵对角线元素做二分查找,如果有相等的,返回true,否则该数出现在刚好比他大的那个数a[i][i]上方和左方,,然后在a[0][i]到a[i][i]和a[i][0]到a[i][i]对该数做二分查找,如果相等返回true,否则返回false
  4. 第二题:
  5. 呵呵,我是学数学的:
  6. 1、f(n)=f(n-1)+f(n-2)  f(1)=1 f(2)=2
  7. 2、f(n)=f(n-1)+f(n-2)+...+f(1)+1 f(1)=1
复制代码
补充:
第一题被误导了,没有考虑到不是方阵的情况,不过也没关系,不是方阵把他补成方阵,酌情加1,这样来只用进行两次较长边的二分查找,从算法复杂度来说应该是优于22L的方法,不过22L的方法非常不错。

论坛徽章:
0
78 [报告]
发表于 2011-12-11 11:13 |只看该作者
学习了。

第一题到真没想到二分查找。
第二题也只考虑到递归,没想到2^(N-1)。

论坛徽章:
0
79 [报告]
发表于 2011-12-11 16:49 |只看该作者
本帖最后由 hbmhalley 于 2011-12-11 16:58 编辑

回复 76# jjboy110

将该数与矩阵对角线元素做二分查找,如果有相等的,返回true,否则该数出现在刚好比他大的那个数a[ i ][ i ]上方和左方,,然后在a[ 0 ][ i ]到a[ i ][ i ]和a[ i ][ 0 ]到a[ i ][ i ]对该数做二分查找,如果相等返回true,否则返回false


    1 2 3
    4 5 6
    7 8 9

    Query = 3

    怎么找

论坛徽章:
0
80 [报告]
发表于 2011-12-11 22:03 |只看该作者
回复 78# hbmhalley

你说的没错,我思路是错误的。
    我同意22L是最佳答案
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP