zoukankan      html  css  js  c++  java
  • 传说中的华为面试题(8分钟写出代码)

      这个题目是在网上看到了,题目描述如下:有两个数组a,b,大小都为n,数组元素的值任意,无序。要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小。不知道是否真的出自华为,但题目难度很大,以我的水平8分钟确实无法写出完整的代码,查阅网上的牛人的思路,理解整理如下:

    1. 对两个数字值进行累加,设差值 A = sum(a) - sum(b)
    2. a的第i个元素和b的第j个元素交换后,a和b的和之差为:A' = sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i]) = sum(a) - sum(b) - 2 (a[i] - b[j]) = A - 2 (a[i] - b[j])
    3. 设x = a[i] - b[j],带入上式得,|A| - |A'| = |A| - |A-2x|
    4. 假设A > 0,当x 在 (0,A)之间时,做这样的交换才能使得交换后的a和b的和之差变小,x越接近A/2效果越好,如果找不到在(0,A)之间的x,则当前的a和b就是答案。

      算法描述为:将a、b两个数组看出天平两端,各自寻找使得x在(0,A)之间并且最接近A/2的i和j,交换相应的i和j元素,重新计算A后,重复前面的步骤直至找不到(0,A)之间的x为止。根据算法描述实现代码:

      1 int SwapArray(int *a, int *b, int n)
      2 {
      3     int nSumA=0, nSumB=0;            //分别记录两个数组的和
      4     int nSumDiff=0, nNumDiff=0;        //nSumDiff表示每轮数组和的差值,nNumDiff表示每轮数组各选两数之差
      5 
      6     float dHalfDiffSum=0.0f, dClose2SumDiff=0.0f;        //dHalfDiffSum表示nSumDiff/2, dClose2SumDiff表示每轮最接近dHalfDiffSum的数
      7 
      8     int nIndexI=0, nIndexJ=0;
      9     bool bDesc=false, bSwitch=false;        //bDesc为true表示 nSumA > nSumB,bSiwtch为true表示 nNumDiff < nSumDiff,此轮无需交换
     10 
     11     int i=0, j=0;
     12     while(1)
     13     {
     14         for(i=0; i!=n; i++)
     15         {
     16             nSumA += a[i];
     17             nSumB += b[i];
     18         }
     19         nSumDiff = nSumA - nSumB;
     20         dHalfDiffSum = (float)nSumDiff/2;
     21         dClose2SumDiff = dHalfDiffSum;
     22         bDesc = nSumA >= nSumB? true : false;
     23         if(bDesc)
     24         {
     25             for(i=0; i!=n; i++)
     26                 for(j=0; j!=n; j++)
     27                 {
     28                     nNumDiff = a[i]-b[j];
     29                     cout<<__LINE__<<" nSumDiff = "<<nSumDiff<<"    dHalfDiffSum = "<<dHalfDiffSum<<" "<<"dClose2SumDiff = "<<dClose2SumDiff<<"    "<<"nNumDiff = "<<nNumDiff<<endl;
     30                     //当在SumA>SumB时,考虑满足交换的条件:1. a[i]<b[j]此时交换只会使SumA更大于SumB,使得SumA-SumB>nSumDiff  2. a[i]-b[j]>SumA-Sumb此时交换同样使得|SumA-SumB|>nSumDiff,这两者条件下都会使两个数组差值越来越大,故需要进行如下过滤
     31                     if(nNumDiff > 0 && nNumDiff < nSumDiff)
     32                     {
     33                         if(nNumDiff >= dHalfDiffSum)
     34                         {
     35                             if(nNumDiff - dHalfDiffSum < dClose2SumDiff)
     36                             {
     37                                 bSwitch = true;
     38                                 dClose2SumDiff = nNumDiff- dHalfDiffSum;
     39                                 nIndexI = i;
     40                                 nIndexJ = j;
     41                                 cout<<__LINE__<<" nIndexI = "<<nIndexI<<" nIndexJ = "<<nIndexJ<<" dClose2SumDiff = "<<dClose2SumDiff<<endl;
     42                             }
     43                         }
     44                         else
     45                         {
     46                             if(dHalfDiffSum - nNumDiff < dClose2SumDiff)
     47                             {
     48                                 bSwitch = true;
     49                                 dClose2SumDiff = dHalfDiffSum - nNumDiff;
     50                                 nIndexI = i;
     51                                 nIndexJ = j;
     52                                 cout<<__LINE__<<" nIndexI = "<<nIndexI<<" nIndexJ = "<<nIndexJ<<" dClose2SumDiff = "<<dClose2SumDiff<<endl;
     53                             }
     54                         }
     55                     }
     56                 }
     57         }
     58         else
     59         {
     60             for(i=0; i!=n; i++)
     61                 for(j=0; j!=n; j++)
     62                 {
     63                     nNumDiff = a[i]-b[j];
     64                     cout<<__LINE__<<" nSumDiff = "<<nSumDiff<<" dHalfDiffSum = "<<dHalfDiffSum<<" "<<"dClose2SumDiff = "<<dClose2SumDiff<<"    "<<"nNumDiff = "<<nNumDiff<<endl;
     65                     if(nNumDiff < 0 && nNumDiff < nSumDiff)
     66                     {
     67                         if(nNumDiff > dHalfDiffSum)
     68                         {
     69                             if(nNumDiff - dHalfDiffSum < dClose2SumDiff)
     70                             {
     71                                 bSwitch = true;
     72                                 dClose2SumDiff = nNumDiff-dHalfDiffSum;
     73                                 nIndexI = i;
     74                                 nIndexJ = j;
     75                                 cout<<__LINE__<<" nIndexI = "<<nIndexI<<" nIndexJ = "<<nIndexJ<<" dClose2SumDiff = "<<dClose2SumDiff<<endl;
     76                             }
     77                         }
     78                         else
     79                         {
     80                             if(dHalfDiffSum - nNumDiff < dClose2SumDiff)
     81                             {
     82                                 bSwitch = true;
     83                                 dClose2SumDiff = dHalfDiffSum-nNumDiff;
     84                                 nIndexI = i;
     85                                 nIndexJ = j;
     86                                 cout<<__LINE__<<" nIndexI = "<<nIndexI<<" nIndexJ = "<<nIndexJ<<" dClose2SumDiff = "<<dClose2SumDiff<<endl;
     87                             }
     88                         }
     89                     }
     90                 }
     91         }
     92 
     93         if(!bSwitch)
     94             break;
     95 
     96         swap(a[nIndexI], b[nIndexJ]);
     97 
     98         for(i=0; i!=n; i++)
     99             cout<<a[i]<<"    ";
    100         cout<<endl;
    101 
    102         for(i=0; i!=n; i++)
    103             cout<<b[i]<<"    ";
    104         cout<<endl;
    105 
    106         nSumA = nSumB =0;
    107         bDesc = bSwitch = false;
    108     }
    109 
    110     return 0;
    111 }
    112 
    113 int _tmain(int argc, _TCHAR* argv[])
    114 {
    115     int a[] = {5, 10,22};
    116     int b[] = {1, 4, 3};
    117 
    118     SwapArray(a, b, 3);
    119 
    120     return 0;
    121 }
  • 相关阅读:
    Spring MVC(1)Spring MVC的初始化和流程以及SSM的实现
    Spring(四)Spring与数据库编程
    MyBatis(4)-- 动态SQL
    MyBatis(3)-- Mapper映射器
    MyBatis(2)-- MyBatis配置mybatis-config.xml
    MyBatis(1)-- MyBatis介绍
    计算机网络(2)-- URL、HTTP、HTTPS、HTML
    计算机网络(1)- TCP
    Shell脚本编程
    和为定值的多个数
  • 原文地址:https://www.cnblogs.com/Tour/p/4055536.html
Copyright © 2011-2022 走看看