leetcode-421 陣列中兩個數的最大異或值 字首樹
阿新 • • 發佈:2021-10-16
leetcode-421 陣列中兩個數的最大異或值 字首樹
1. 題目
給你一個整數陣列 nums ,返回 nums[i] XOR nums[j] 的最大運算結果,其中 0 ≤ i ≤ j < n 。
2. 思路
-
暴力解法通過雙層for迴圈求出最大的異或結果,時間複雜度為\(O(n^2)\) 超時
-
字首樹
一個整數的二進位制串只有0和1,因此可以將所有位放在一顆字首樹中,在一棵字首樹中查詢某個樹的複雜度為O(logn),因此已知一棵字典樹,查詢樹中與它最大異或值最大的複雜度為O(logn)
求異或值的最大值,應該讓該結果中的每一個儘可能為1
查詢過程:
輸入數字不超過2^31,因此遍歷該數的每一位,
-
如果該位為1,則在樹中選擇的節點為0,建立字首樹時,0作為左樹,1作為右數,如果沒有左樹,則選擇右樹
-
如果該位為0,則在樹中選擇右樹,若沒有右樹則選擇左樹
在查詢時,如果選擇的時不同的值,即\(0\bigoplus 1\),此時的異或結果為\(x=x*2+1\),增加了一位,且末位為1,
若是\(0\bigoplus 0\)和\(1\bigoplus 1\),此時的\(x=x*2\)
如圖,對於25,和字首樹相比,第一位時1,則在字首樹第一層選擇(0),第二位是1,字首樹中選擇(0,0),第三位時0,字首樹中選擇(0,0,1),第四位是0,字首樹中第四位本應選擇1,但此時節點只有左節點,因此字首樹中選擇(0,0,1,1),第五位是1,字首樹中選擇(0,0,1,0,1)
-
3. Code
-
暴力解法
class Solution: def findMaximumXOR(self, nums: List[int]) -> int: res=float("-inf") length=len(nums) for i in range(length): for j in range(i,length): res=max(res,nums[i]^nums[j]) return res
-
字首樹
class TreeNode: def __init__(self,left=None, right=None): self.left = left self.right = right class Solution: def findMaximumXOR(self, nums: List[int]) -> int: root=TreeNode() def add(n): cur=root for k in range(30,-1,-1): bit=(n>>k)&1 if bit==0: if not cur.left: cur.left=TreeNode() cur=cur.left else: if not cur.right: cur.right=TreeNode() cur=cur.right def check(num): cur=root x=0 for i in range(30,-1,-1): bit=(num>>i)&1 if bit==0: if cur.right: cur=cur.right x=x*2+1 else: cur=cur.left x*=2 else: if cur.left: cur=cur.left x=x*2+1 else: cur=cur.right x*=2 return x x=0 for i in range(1,len(nums)): add(nums[i-1]) x=max(x,check(nums[i])) return x