問題分析:如果要很好的解決找到兩個不同的數字,我們先來看乙個簡單地例子:
如果只有乙個數字出現了一次,其他都出現了兩次,那仫我們利用異或的特性:「不同為1,相同為0」可以很容易的解決,就是用0與陣列中每乙個元素相異或得到不同的那個數字。
可是如果存在兩個不同的數字應該如何找到他們呢?
以下先給出程式的測試**:
int main()
; sz=sizeof(arr)/sizeof(arr[0]);
differ_check(arr,sz);
system("pause");
return 0;
}
我們是不是可以這樣做呢?
.先用0來異或陣列中的所有元素,得到那兩個沒有重複出現數字的異或結果,陣列中重複出現的數字就為0了;
.既然兩個數字沒有重複出現那仫他們肯定是不同的,當然他們異或的結果肯定不是0,那仫我們是不是可以考慮利用這個異或的結果將這個陣列中的元素分成倆個部分,這兩個部分將沒有重複出現的數字分到兩個組裡,並且在這兩個組裡分別異或陣列中每個元素右移count(用來記錄兩個沒有重複出現的數字異或結果1的位數)位來實現呢?當然是可以的啦!
.如何在沒有重複出現數字異或結果裡區別出那兩個數字呢?
下面我們來看乙個簡單地例子:
1,2,3,4,2,1 3和4異或的結果是111,
而3的二進位制是011,4的二進位制是100,
可以發現這兩個數字從左往右數第一位是不同的
所以要區分這兩個數字就要取出這個不同的位
我們就通過這個1將陣列劃分成兩個部分,並記錄這個1所在的位數,將陣列中所有的元素都右移這個1所在的位數,再次把陣列裡的所有元素右移該位,在不同的部分異或找到沒有重複出現的數字。
下面我們來看這個函式**的實現部分:
void differ_check(int arr,int sz)
for(i=0;i> count)&1)
else
}printf("%d %d沒有匹配成功\n",a,b);
}
以上實現中沒有給出標頭檔案,讀者可自行新增;
通過上述例子使我更加深入的理解了異或的特性並且對位運算有了較好的把握,也理解了用位運算實現的小演算法題。希望再接再厲。
劍指offer 刪除重複節點
package 刪除重複節點 需要兩個指標,乙個指向前乙個節點prenode,另乙個指向當前節點node,如果遇到相等的節點,node向後移動,prenode不動,存下node.val方便後面的比較,直到遇到node和node.next不相等,prenode就可以指向node.next 注意 鍊錶開...
劍指offer 醜數(找規律)
把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。醜數的序列為 每個醜數都是前面某乙個醜數乘上2 3 5的結果。所以新加入的醜數必然是從原有醜數中與2,3,5乘積中最小的值...
劍指offer之陣列中重複的數
在乙個長度為n的陣列裡的所有數字都在0到n 1的範圍內。陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼對應的輸出是第乙個重複的數字2。public class solution a numbers i ...