1. 程式人生 > >421. Maximum XOR of Two Numbers in an Array

421. Maximum XOR of Two Numbers in an Array

可變 這樣的 TE 固定 需要 AI class turn copy

這題要求On時間復雜度完成, 第一次做事沒什麽思路的, 答案網上有不貼了, 總結下這類題的思路.

不局限於這個題, 凡是對於這種給一個 數組, 求出 xxx 最大值的辦法, 可能上來默認就是dp, 但是註意如果要求On復雜度, 毫無疑問是不能用dp的, 因為dp至少是On2了對吧.

那麽需要處理的元素長度為N, 如何在On實現呢, 關鍵點在於" 反推" 的思路, 我這裏反推的意思是 從結果推倒, 而不是通過數據一個個計算看是否滿足結果.

舉例, 一般DP題目就是使用 dp[x] 這樣的變量來保存結果, 然後遍歷所有數據完成得到答案, 把這種思路稱之為正推法.

那麽, 反過來, "遍歷答案" 找出是否存在就是反推了.

以這題為例, 答案的解法是從最高位開始,一步步判斷是否存在 a和b 使得 a^b 最大, 要一個int值最大,毫無疑問就是每位都是1,

所以 用偽代碼來表示思想就是

for i= 0xfffffff -> 0
      if exist   a ^ b = i   
           break;  

得到這個思想以後, 使用一個hash結構來保存所有的數組元素就可以變為On復雜度, 因為要求的是存在與否, 不需要順序, hash就恰好解決了這個問題

首先得出基本思路

問題:  在數組A 裏面求滿足 xxx 條件的 最大/小 值  B ?   要求Ai ^ Aj = B

copy  A to   Hash<int> C
for max = 0xffffffff -> 1
    for Ai in A 
        for  Aj  in B
            if  Ai ^ Aj = max    return


這樣有三重循環, 開始優化
for max = 0xffffffff -> 1  可變為按位處理  for  i = 32->1   , 32位整數, 從最高位開始處理
for Ai in A 
        for  Aj  in B    這有兩重循環, 使用hash可以去掉一層循環

由於xor操作存在交換律  a^b=c  可以得到  a^c=b ;

最終結論  偽代碼

max=0
mask=0
for i = 32 -> 1
  mask=mask| 1<<i mask得到第i位是1的數; 第一輪mask是 100000, 第二輪 11000  第三輪 1110000 ...
  for Ai in A  對數組的每個元素存儲第i位
    Ai & 1<<i - >  hash  存入hash
  for hi in hash
    if max ^ hi  in hash  我們要求 a ^ b = 最大數,  反過來這裏判斷  最大數 ^ a 是否存在於hash
      更新max值
好了 這裏 仍然有個 32到1 的循環, 由於是固定次數, 所以真正的循環只有for Ai in A  和  for hi in  hash , 兩者沒有嵌套關系, 也就是On復雜度了

  

421. Maximum XOR of Two Numbers in an Array