421 陣列中兩個數的最大異或值

2022-09-09 14:30:22 字數 2306 閱讀 9089

標籤:位運算、字典樹。

題目

給你乙個整數陣列 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 解釋 最大的結...