Input: nums =[1,2,3,4,5]Output: 7Explanation: There are 11 strong pairs in the array nums:(1,1),(1,2),(2,2),(2,3),(2,4),(3,3),(3,4),(3,5),(4,4),(4,5) and (5,5).The maximum XOR possible from these pairs is3 XOR 4=7.
Input: nums =[10,100]Output: 0Explanation: There are 2 strong pairs in the array nums:(10,10) and (100,100).The maximum XOR possible from these pairs is10 XOR 10=0 since the pair(100,100) also gives 100 XOR 100=0.
Input: nums =[500,520,2500,3000]Output: 1020Explanation: There are 6 strong pairs in the array nums:(500,500),(500,520),(520,520),(2500,2500),(2500,3000) and (3000,3000).The maximum XOR possible from these pairs is500 XOR 520=1020 since the only other non-zero XOR value is2500 XOR 3000=636.
To maximize the XOR for strong pairs efficiently, sort the array and use a sliding window to maintain the valid range for each number. For each number, use a trie to quickly find the number in the window that gives the maximum XOR.
classTrie { val child = arrayOfNulls<Trie>(2) }
classSolution {
funmaximumStrongPairXor(nums: IntArray): Int {
nums.sort()
var ans = 0; var l = 0for (r in nums.indices) {
while (l < r && nums[r] - nums[l] > nums[l]) l++val root = Trie()
for (i in l until r) insert(root, nums[i])
if (r > l) ans = maxOf(ans, query(root, nums[r]))
}
return ans
}
funinsert(root: Trie, x: Int) {
var node = root
for (i in16 downTo 0) {
val b = (x shr i) and 1if (node.child[b] ==null) node.child[b] = Trie()
node = node.child[b]!! }
}
funquery(root: Trie, x: Int): Int {
var node = root; var res = 0for (i in16 downTo 0) {
val b = (x shr i) and 1if (node.child[1-b] !=null) {
res = res or (1 shl i)
node = node.child[1-b]!! } else node = node.child[b]!! }
return res
}
}
classTrie:
def__init__(self):
self.child = [None, None]
classSolution:
defmaximumStrongPairXor(self, nums: list[int]) -> int:
nums.sort()
ans, l =0, 0for r, x in enumerate(nums):
while l < r and x - nums[l] > nums[l]:
l +=1 root = Trie()
for i in range(l, r):
node = root
for b in range(16, -1, -1):
bit = (nums[i] >> b) &1ifnot node.child[bit]:
node.child[bit] = Trie()
node = node.child[bit]
if r > l:
node = root
res =0for b in range(16, -1, -1):
bit = (x >> b) &1if node.child[1-bit]:
res |=1<< b
node = node.child[1-bit]
else:
node = node.child[bit]
ans = max(ans, res)
return ans
structTrie { child: [Option<Box<Trie>>; 2] }
impl Trie { fnnew() -> Self { Trie { child: [None, None] } } }
impl Solution {
pubfnmaximum_strong_pair_xor(nums: Vec<i32>) -> i32 {
letmut nums = nums;
nums.sort();
letmut ans =0;
letmut l =0;
for r in0..nums.len() {
while l < r && nums[r] - nums[l] > nums[l] { l +=1; }
letmut root = Trie::new();
for i in l..r {
letmut node =&mut root;
for b in (0..=16).rev() {
let bit = (nums[i] >> b) &1;
node = node.child[bit asusize].get_or_insert_with(|| Box::new(Trie::new()));
}
}
if r > l {
letmut node =&root;
letmut res =0;
for b in (0..=16).rev() {
let bit = (nums[r] >> b) &1;
iflet Some(ref next) = node.child[1-bit asusize] {
res |=1<< b;
node = next;
} elseiflet Some(ref next) = node.child[bit asusize] {
node = next;
}
}
ans = ans.max(res);
}
}
ans
}
}
⏰ Time complexity: O(n^2 log M), where n is the length of nums and M is the max value in nums. For each number, we may build a trie of up to n numbers, each with up to log M bits.
🧺 Space complexity: O(n log M), for the trie at each step.