421. 数组中两个数的最大异或值
给你一个整数数组 nums
,返回 nums[i] XOR nums[j]
的最大运算结果,其中 0 ≤ i ≤ j < n
。
示例 1:
1 2 3
| 输入:nums = [3,10,5,25,2,8] 输出:28 解释:最大运算结果是 5 XOR 25 = 28.
|
示例 2:
1 2
| 输入:nums = [14,70,53,83,49,91,36,80,92,51,66,70] 输出:127
|
提示:
1 <= nums.length <= 2 * 10^5
0 <= nums[i] <= 2^31 - 1
按位哈希:对于每一位,用哈希表记录之前出现的数,用哈希表判断newRes是否可能成立
如果 a⊕b=newAns
,那么两边同时异或 b
,由于 b⊕b=0
,所以得到 a=newAns⊕b
(相当于把两数之和代码中的减法改成异或)
这样就可以一边枚举 b
,一边在哈希表中查找 newAns⊕b
了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public int findMaximumXOR(int[] nums) { int n = nums.length, max = Arrays.stream(nums).max().getAsInt(); int highBit = 31 - Integer.numberOfLeadingZeros(max); int res = 0, mask = 0; Set<Integer> vis = new HashSet<>(); for (int i = highBit; i >= 0; i--) { vis.clear(); mask |= 1 << i; int newRes = res | (1 << i); for (int x : nums) { x &= mask; if (vis.contains(newRes ^ x)) { res = newRes; break; } vis.add(x); } } return res; } }
|
字典树,search的时候往取反的值找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| class Trie { class TrieNode { boolean end; TrieNode[] children = new TrieNode[2]; } TrieNode root = new TrieNode(); void insert(int word) { TrieNode cur = root; for (int i = 30; i >= 0; i--) { int index = word >> i & 1; if (cur.children[index] == null) { cur.children[index] = new TrieNode(); } cur = cur.children[index]; } cur.end = true; } int search(int word) { TrieNode cur = root; int res = 0; for (int i = 30; i >= 0; i--) { int index = word >> i & 1; if (cur.children[index ^ 1] == null) { cur = cur.children[index]; } else { res |= 1 << i; cur = cur.children[index ^ 1]; } } return res; } } class Solution { public int findMaximumXOR(int[] nums) { int n = nums.length, res = 0; Trie tree = new Trie(); for (int x : nums) { tree.insert(x); res = Math.max(res, tree.search(x)); } return res; } }
|