# 2020q3 Homework4 (quiz4) contributed by < `johnnycck` > ## 測驗一 此題需要完成可以實作出兩整數的 Hamming distance。 ```cpp int hammingDistance(int x, int y) { return __builtin_popcount(x OP y); } ``` * ans: OP = ^,因為要算 Hamming Distance,使用 ^ ,兩者相異才會顯示出來,再透過 __builtin_popcount( ),得到有幾個 '1',及是 Hamming Distance。 :::success 延伸問題: 練習 LeetCode 477. Total Hamming Distance,你應當提交 (submit) 你的實作 (C 語言實作),並確保執行結果正確且不超時 ::: * 我試圖提交上面程式碼的延伸,但卻得到 TLE (Time Limit Exceeded) ```c= int hammingDistance(int x, int y) { return __builtin_popcount(x ^ y); } int totalHammingDistance(int* nums, int numsSize){ int ans=0; for(int i=0; i<numsSize; i++) { for(int j=i+1; j<numsSize; j++) { ans += hammingDistance(*(nums+i),*(nums+j)); } } return ans; } ``` * 經過嘗試後,發現寫不出來,因此去看別人的 discussion,我參考了其中一個解答 ```c= int totalHammingDistance(int* nums, int numsSize) { /* record each bit 1's number, each bits total hamming distance: countone*(numsSize - countone) */ int count_one = 0; int number = 0; /*32(can decrease to least 30) bits is enough to repreent 10^9*/ for(int i = 0;i < 30;i++) { /*init count_one of each bits*/ count_one = 0; for(int j = 0;j < numsSize;j++) { if(nums[j]&1 == 1) { count_one++; } nums[j] = nums[j] >> 1; } number = number + count_one * (numsSize - count_one); } return number; } ``` * 解釋程式碼流程: 1. 他的解法是一次比對同一個 Bit Position 的全部 input,假設 input 是 4, 14, 2,以二進為表示就是 * | Input \ Bit Position | 3 | 2 | 1 |0 | | -------- | -------- | -------- |-------- |-------- | |4| 0 | 1 | 0 |0 | |14| 1 | 1 | 1 |0 | |2| 0 | 0 | 1 | 0 | 2. 先比對 Position 0,把有 '1' 的個數跟有 '0' 的個數相乘,最後再將每個 Position 的答案相加 (i 設為 32 是因為 input 最大是 10^9,不過 30 其實就可以表達 10^9) 1. 以此題為例,可以得到 2 + 2 + 2 + 0 * 原先我的思考流程就是要將所有的 input 都相互比過一次,但這樣時間複雜度會是 O(N^2),較佳的解法是以 position 的方式,將每個 input 的同一個 position 比對過,再相加起來,而這個動作可以由 '1' 的個數跟 '0' 的個數相乘得到,這是因為 '1' 的個數代表同一個 '0' 會跟幾個 1 產生 hamming distance,而 '0' 的個數就代表有幾個前述的 '0',所以相乘就會是某個 position 的總 hamming distance