標籤:位運算、字典樹。
題目給你乙個整數陣列 nums ,返回 nums[i] xor nums[j] 的最大運算結果,其中 0 ≤ i ≤ j < n 。
高階:你可以在 o(n) 的時間解決這個問題嗎?
輸入:nums =[3
,10,5
,25,2
,8]輸出:28
解釋:最大運算結果是 5 xor 25
=28.
輸入:nums =[0
]輸出:0
輸入:nums =[2
,4]輸出:6
輸入:nums =[8
,10,2
]輸出:10
輸入:nums =[14
,70,53
,83,49
,91,36
,80,92
,51,66
,70]輸出:127
1<= nums.length <=2*
10^40
<= nums[i]
<=2^
31-1
分析不會字典樹怎麼辦?直接暴力唄,過不過聽天由命。
暴力法:
class
solution
}return res;
}}
時間複雜度o(n ^ n),空間複雜度o(1)
一般情況下,暴力破解肯定是要涼涼的。所以有必要學習一下字典樹怎麼解決這類問題。
trie,又稱字首樹或字典樹,是一棵有根樹。對於這題,我們可以將每個數轉換成二進位制的形式01,那麼就可以用一顆二叉樹表示乙個數,定義左節點指向0,右節點指向1,那麼從根節點到葉子節點總共有33層(加上root,32位表示乙個數,不足的補0)。
那麼對於題目要求的【給你乙個整數陣列 nums ,返回 nums[i] xor nums[j] 的最大運算結果,其中 0 ≤ i ≤ j < n 。】遍歷陣列,將每個數進行拆分存入字典樹,對於任意下標j,下標[0, j - 1]的數都已經存入了數中,只需要拆分num[j]然後逐層去匹配,盡量保證num[j]的每一位和樹的每一層值不一樣,這樣異或後結果為1,遍歷完每一位後,得到的數就是【nums[i] xor nums[j] 的最大運算結果,其中 0 ≤ i ≤ j < n 】。
class
solution
// 全域性變數,一直累計前面數的值
tree root =
newtree()
;private
static
final
int max_bit =31;
/** * 這個函式是計算num的各個位數,將每一位存入tree中
*/private
void
split
(int num)
node = node.right;
}else
node = node.left;}}
}/**
* 假設num對應的下標為i,那麼這個函式是為了求得nums[i]與num[j]的最大亦或值
* 其中j <= i,[0, j]下標對應的數,都已經按位拆分到了tree中,
* 這裡只需要從高位開始,拆分num,對於每一位,只需要在tree中找到與num相反的位,異或即為1,
* 如此下來,每一層盡量讓亦或值為1,得到的就是最大的異或值。
* 注意:從tree的根節點到葉子節點,表示乙個數。
LC 陣列中兩個數的最大異或值
根據圖進行理解 題目中說到最大數小於2的31次方,所以for迴圈31次即可 先確定高位,再確定低位 貪心演算法 才能保證這道題的性質 1位接著1位去確定這個數的大小 主要思路 構造具備公共字首的字典樹,每次遍歷數字,如果當前數字高位為1時,判斷是否存在0的支路 如果當前數字低位數字為0時,判斷當前是...
leetcode421 陣列中兩個數的最大異或值
給定乙個非空陣列,陣列中元素為 a0,a1,a2,an 1,其中 0 ai 231 找到 ai 和aj 最大的異或 xor 運算結果,其中0 i,j n 你能在o n 的時間解決這個問題嗎?示例 輸入 3 10,5 25,2 8 輸出 28解釋 最大的結果是 5 25 28.構建乙個字典樹 深度是3...
LeetCode421 陣列中兩個數的最大異或值
目錄 一 題目描述 二 解題思路 三 實現 給定乙個非空陣列,陣列中元素為 a0,a1,a2,an 1,其中 0 ai 231 找到 ai 和aj 最大的異或 xor 運算結果,其中0 i,j n 你能在o n 的時間解決這個問題嗎?示例 輸入 3,10,5,25,2,8 輸出 28 解釋 最大的結...