免费注册 查看新帖 |

Chinaunix

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

华为面试题(8分钟写出代码) [复制链接]

论坛徽章:
0
311 [报告]
发表于 2012-01-16 11:29 |只看该作者
回复 1# forrestgang


    我觉得排序没有什么意义的,因为这两个数组里面的值肯定会交换,交换完了之后还是乱序的。
这是小弟我写的,自测没有什么问题。

  1. #include <stdlib.h>
  2. #include <stdio.h>

  3. #define ARRAY_NUM   3

  4. int a[ARRAY_NUM] = {1,2,3};
  5. int b[ARRAY_NUM] = {4,5,6};
  6. void swap(int* a, int* b)
  7. {
  8.         int t = *a;
  9.         *a = *b;
  10.         *b = t;
  11. }

  12. int sum(int a[], int num)
  13. {
  14.         int sum = 0;
  15.         int i = 0;
  16.         for(i = 0; i < num; i++)
  17.         {
  18.                 sum += a[i];
  19.         }
  20.         return sum;
  21. }


  22. void func(int a[], int b[], int num)
  23. {
  24.         int sum_a = sum(a, num);
  25.         int sum_b = sum(b, num);

  26.         int b_swap = 0;
  27.         int i = 0;
  28.         int j = 0;
  29.         int sum_diff = sum_a - sum_b;
  30.         printf("diff:%d\n", sum_diff);
  31.         while (1)
  32.         {
  33.                 for (i = 0; i < num; i++)
  34.                 {
  35.                         for(j = 0; j < num; j++)
  36.                         {
  37.                                 int diff = a[i] - b[j];
  38.                                 if (abs(sum_diff) > abs(sum_diff - (2 * diff)))
  39.                                 {
  40.                                         swap(a + i, b + j);
  41.                                         b_swap = 1;
  42.                                         sum_diff = sum_diff - (2 * diff);
  43.                                         printf("diff:%d\n", sum_diff);
  44.                                         break;
  45.                                 }
  46.                         }
  47.                         if(b_swap > 0)
  48.                         {
  49.                                 break;
  50.                         }
  51.                 }
  52.                 if (0 == b_swap)
  53.                 {
  54.                         break;
  55.                 }
  56.                 else
  57.                 {
  58.                         b_swap = 0;
  59.                 }
  60.         }
  61. }

  62. void _print()
  63. {
  64.         int i = 0;
  65.         printf("array a:\n");
  66.         for(i = 0; i < ARRAY_NUM; i++)
  67.         {
  68.                 printf("%d ", a[i]);
  69.         }
  70.         printf("\n");

  71.         printf("array b:\n");
  72.         for(i = 0; i < ARRAY_NUM; i++)
  73.         {
  74.                 printf("%d ", b[i]);
  75.         }
  76.         printf("\n");
  77. }

  78. int main()
  79. {
  80.         printf("before:\n");
  81.         _print();

  82.         func(a, b, ARRAY_NUM);
  83.         printf("\n\n");
  84.         printf("after:\n");
  85.         _print();

  86.         return 0;
  87. }
复制代码

论坛徽章:
0
312 [报告]
发表于 2012-02-09 13:14 |只看该作者
lz看下这组测试数据 {10000,1005,105,10} {10004,1000,100,14} 貌似你的贪婪只适合特殊情况

论坛徽章:
0
313 [报告]
发表于 2012-02-15 19:19 来自手机 |只看该作者
absuma-sumbhalfdiff
     翪sumasumba[n]ab[1]bСhalfdiffбСa[n]b[1]òa[n]-b[2]halfdiffa[n]-b[3]ia[n]-b[i]Сhalfdiffa[n]-b[i]halfdifftempdiffa[n-1]-b[1]tempdiffСa[j]b[i]нtempdiff0
     halfdiffhalfdiffС0tempdiff0

论坛徽章:
0
314 [报告]
发表于 2012-02-15 19:23 |只看该作者
开始先分别将a、b两个数组排序,然后算出两个数组的累和之差suma-sumb的一半,就记作halfdiff吧,开始循环
     比如开始时suma大于sumb,那就用a[n](a中最大)减去b[1](b中最小),将这个差值与halfdiff进行比较,如果小于,则交换a[n]和b[1],交换时也要保证两个数组仍然有序,可以用插入排序;如果大于,则用a[n]-b[2]再与halfdiff比较,如果仍大于,再用a[n]-b[3]…一直找到一个i使a[n]-b[i]小于halfdiff,将a[n]-b[i]与halfdiff的差值存入tempdiff,接着用a[n-1]-b[1]…即找到使tempdiff最小的a[j]和b[i]进行交换(仍保持有序);如果tempdiff为0,则幸运结束。
     再计算新的halfdiff,进行下一轮循环,直到halfdiff最小或为0或tempdiff为0。

论坛徽章:
3
寅虎
日期:2013-11-27 07:53:29申猴
日期:2014-09-12 09:24:152015年迎新春徽章
日期:2015-03-04 09:48:31
315 [报告]
发表于 2012-02-15 21:22 |只看该作者
一个一个取出,天平左边重就放右边,右边重就放左边。

论坛徽章:
0
316 [报告]
发表于 2012-02-24 18:07 |只看该作者
..这个挖坟也挖的太厉害了吧。

第一步 取TotalA-TotalB的绝对值,设为Difference
第二步 如果TotalA>TotalB,a[n]中每个元素减去b[n]中每个元素,大于0放到GTmp[n][n],小于0放到LTmp[n][n],为0的丢弃
第三步 GTmp[n][n]中取1,.....n个元素的所有组合,组合中元素的总和Total与Difference比较,如果为0则得出最优解,否则取最小偏差为LikelyAnswer1,
          保存Total到GResult[x]
第四步 LTmp[n][n]中取1,.....n个元素的所有组合,组合中元素的总和Total保存到LResult[y]
第五步 遍历GResult[x]和LResult[x]各取1个元素进行求和,将求和结果与Difference比较,如果为0则得出最优解,否则取最小偏差为LikelyAnswer2
第六步 比较LikelyAnswer1和LikelyAnswer2,取小值作为最优解

论坛徽章:
0
317 [报告]
发表于 2012-02-24 20:51 |只看该作者
汗,真的是华为面试题??
前两天去了南京华为的面试,面试上机题比这个简单多了,题目是:
有一个数组,已知长度大于2,然后要求完成一个函数,入参为那个数组和两个指针,取得数组中最大和次大的两个数并用指针返回。

论坛徽章:
0
318 [报告]
发表于 2012-02-25 12:20 |只看该作者
本帖最后由 j3kljs02398j 于 2012-02-25 12:32 编辑

思路:将ab统一排序,然后在成对分发回ab,相对大的放在a,另一个放在b。
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <time.h>
  4. #define LENGTH 3000
  5. /*
  6. * 有两个数组a,b,大小为n, 无序
  7. * 通过交换a,b中的元素,使数组a元素和数组b元素之间的差最小
  8. */
  9. int cmp(const void *a1, const void *a2)
  10. {
  11.         int v1 = *((int *)a1);
  12.         int v2 = *((int *)a2);

  13.         if (v2 == v1)
  14.                 return 0;
  15.         return v2 > v1 ? 1 : -1;
  16. }

  17. int main(void)
  18. {
  19.         int a[LENGTH];
  20.         int b[LENGTH];
  21.         int *tmp = NULL;
  22.         int i, j;
  23.         int result;

  24.        /*随机初始化数组a,b 别且打印a,b */
  25.         srand((unsigned int )time(NULL));
  26.         for (i = 0; i < LENGTH; i++)  {
  27.                 a[i] = rand()%1000;
  28.                 b[i] = rand()%1000;
  29.         }

  30.         /* 把ab放到一个数组中,然后整体排序*/
  31.         if ((tmp = (int *)malloc(sizeof(int) * LENGTH * 2)) == NULL) {
  32.                 fprintf(stderr, "malloc failed\n");
  33.                 exit(1);
  34.         }
  35.         for (i = j = 0; i < LENGTH * 2;j++) {
  36.                 tmp[i++] = a[j];
  37.                 tmp[i++] = b[j];
  38.         }
  39.         /*对a,b各自排序*/
  40.         qsort(tmp, LENGTH * 2, sizeof(int), cmp);
  41.         /* 排序后在分别放回ab 成对分发,大的在a中 */
  42.         for (i = j = 0; i < LENGTH; i++) {
  43.                 a[i] = tmp[j++];
  44.                 b[i] = tmp[j++];
  45.         }
  46.         free(tmp);
  47.        /* 打印下结果 */
  48.         for (i = 0, result = 0; i < LENGTH; i++)
  49.                 result += a[i] - b[i];
  50.         printf("sum a - sum b is %d\n", result);

  51.         return 0;
  52. }
复制代码
贴出来之后,发现这种思路不对。a{5 5 5} b{10 0 0}

论坛徽章:
0
319 [报告]
发表于 2012-02-25 16:08 |只看该作者
本帖最后由 enough_zerg 于 2012-02-25 16:15 编辑

没找到在哪设置代码格式的啊

思路就是先求出2个数组和的差,然后从数组a开始逐个把数组b的元素替换过来加一下,要是差比原先小的话就真正的换
直到换完,或者遇到差变成0了就不搞了

1 #include <stdio.h>
  2 #include <assert.h>
  3 #include <math.h>
  4
  5 void * swap(int *a, int *b, int n)
  6 {
  7     assert(a != NULL && b != NULL);
  8
  9     int suma = 0;
10     int sumb = 0;
11     int count = 0;
12
13     int k = 0;
14     for (; count < n; count++)
15     {
16         suma += a[count];
17     }
18     for (count = 0; count < n; count++)
19     {
20         sumb += b[count];
21     }
22
23     int diff = abs(suma - sumb);
24
25     int midiff = 0;
26
27     for (count = 0; count < n; count++)
28     {
29         for (; k < n; k++)
30         {
                 //这里把b数组里的对应元素加过来置换作下运算,根据结果决定要不要真的换
31             midiff = abs(suma - a[count] + b[k] - sumb + b[k] - a[count]);
32             if (midiff < diff)
33             {
34                 int tmp = a[count];
35                 a[count] = b[k];
36                 b[k] = tmp;
37                 diff = midiff;
38             }
39             if (midiff == 0)
40                 break;
41         }
42     }
43 }

论坛徽章:
0
320 [报告]
发表于 2012-02-25 23:30 |只看该作者
这道题目非常的难,要写出精妙的算法实属不易!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP