難度中等
給定一個非空陣列,陣列中元素為 a0, a1, a2, … , an-1,其中 0 ≤ ai < 2^31
找到 ai 和 aj 最大的異或 (XOR) 運算結果,其中0 ≤ i , j < n 。
你能在O(n)的時間解決這個問題嗎?
示例:
輸入: [3, 10, 5, 25, 2, 8]
輸出: 28
解釋: 最大的結果是 5 ^ 25 = 28.
暴力法雖然簡單,但是。。。都能想到,而且複雜度很高
異或就是對應bit位上如果相同,那麼兩者運算結果為0,不同則為 1,即:
- 1 ^ 1 = 0 ^ 0 = 0
- 0 ^ 1 = 1 ^ 0 = 1
即要想異或出來的數字大,那麼應該儘量保持兩位是不同的!,這樣對應位異或出來為1,結果才會比較大!
那麼什麼時候最大呢?
儘量使高位異或出 1 才越能保持最大!!!
為什麼呢?因為有 1 * * * *
一定大於 0 * * * *
! 性質
就是不管低位情況如何,只要高位為 1,一定比高位不是 1 的要大, 所以在遍歷過程中,只需要尋找與當前位不同的 ,使其異或結果為 1 即可!如若沒有則並無影響。
這個過程中,可以使用字首樹來儲存每一個數字的各位情況!
儘量尋找高位上不同於當前位的結點則體現貪心
實現方法: 字首樹 + 貪心
package ddx.December.day6;
public class Normal_421 {
public int maxXOR(int[] nums) {
BitTrieNode root = buildBitTrie(nums);
return searchMaXOR(nums,root);
}
//字首樹 + 貪心!
public int searchMaXOR(int[] nums, BitTrieNode root){
int max = -1; //記錄最大值
for(int num : nums){//遍歷陣列,找到每個數字與哪個數字異或結果最大!
BitTrieNode curNode = root;
for(int index = 31;index >= 0;index--){
int curBit = num & (1 << index); //拿到數字最高位
if(curBit == 0){ //如果最高位是0 ,那麼我需要字首樹中對應位為 1 的
curNode = curNode.one != null ? curNode.one:curNode.zero; //儘量尋找 與當前bit位相反的結點!!!!!
}else{ //反之亦然
curNode = curNode.zero != null ? curNode.zero:curNode.one; //儘量尋找 與當前bit位相反的結點!!!!!
}
}
max = Math.max(max,num ^ curNode.val); //更新最大值!此時curode.val就是與 num異或最大的數字!!!
}
return max;
}
public BitTrieNode buildBitTrie(int[] nums) { //建立位元位字首樹
BitTrieNode root = new BitTrieNode(-1); //初始化根節點
for (int num : nums) {
BitTrieNode curNode = root;
for (int index = 31; index >= 0; index--) { //每個數最多不超過32位!將這32位全部建立完
int curBit = num & (1 << index); //拿到當前位
if (curBit == 0) {
if (curNode.zero == null) { //若沒有則建立
curNode.zero = new BitTrieNode(0);
}
curNode = curNode.zero;
} else {
if (curNode.one == null) {//若沒有則建立
curNode.one = new BitTrieNode(1);
}
curNode = curNode.one;
}
}
curNode.val = num; //賦值
}
return root;
}
}
class BitTrieNode {
public BitTrieNode zero;
public BitTrieNode one;
public int val;
BitTrieNode(int val) {
this.val = val;
}
}
輸出結果
與3異或結果最大的數為:25 異或結果為 :26
與10異或結果最大的數為:25 異或結果為 :19
與5異或結果最大的數為:25 異或結果為 :28
與25異或結果最大的數為:5 異或結果為 :28
與2異或結果最大的數為:25 異或結果為 :27
與8異或結果最大的數為:25 異或結果為 :17
本作品採用《CC 協議》,轉載必須註明作者和本文連結