傳說中的華為面試題(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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM