题目描述:

解:
421.数组中两个数的最大异或值的进阶版
此题也是求最大的异或值,同样需要构造一个01字典树。有区别的是:
- 采取离线查询的方法:每次将需要参加筛选的值加入到字典树
- 采取在线查询的方法:一次性将数组所有值加入字典树,再对于每一个查询的值进行判断。
以下代码是抄官解的:
1.离线查询:
class Solution {public int[] maximizeXor(int[] nums, int[][] queries) {Arrays.sort(nums);int numQ = queries.length;int[][] newQueries = new int[numQ][3];for (int i = 0; i < numQ; ++i) {newQueries[i][0] = queries[i][0];newQueries[i][1] = queries[i][1];newQueries[i][2] = i;}Arrays.sort(newQueries, new Comparator<int[]>() {public int compare(int[] query1, int[] query2) {return query1[1] - query2[1];}});int[] ans = new int[numQ];Trie trie = new Trie();int idx = 0, n = nums.length;for (int[] query : newQueries) {int x = query[0], m = query[1], qid = query[2];while (idx < n && nums[idx] <= m) {trie.insert(nums[idx]);++idx;}if (idx == 0) { // 字典树为空ans[qid] = -1;} else {ans[qid] = trie.getMaxXor(x);}}return ans;}}class Trie {static final int L = 30;Trie[] children = new Trie[2];public void insert(int val) {Trie node = this;for (int i = L - 1; i >= 0; --i) {int bit = (val >> i) & 1;if (node.children[bit] == null) {node.children[bit] = new Trie();}node = node.children[bit];}}public int getMaxXor(int val) {int ans = 0;Trie node = this;for (int i = L - 1; i >= 0; --i) {int bit = (val >> i) & 1;if (node.children[bit ^ 1] != null) {ans |= 1 << i;bit ^= 1;}node = node.children[bit];}return ans;}}
2.在线查询
class Solution {public int[] maximizeXor(int[] nums, int[][] queries) {Trie trie = new Trie();for (int val : nums) {trie.insert(val);}int numQ = queries.length;int[] ans = new int[numQ];for (int i = 0; i < numQ; ++i) {ans[i] = trie.getMaxXorWithLimit(queries[i][0], queries[i][1]);}return ans;}}class Trie {static final int L = 30;Trie[] children = new Trie[2];int min = Integer.MAX_VALUE;public void insert(int val) {Trie node = this;node.min = Math.min(node.min, val);for (int i = L - 1; i >= 0; --i) {int bit = (val >> i) & 1;if (node.children[bit] == null) {node.children[bit] = new Trie();}node = node.children[bit];node.min = Math.min(node.min, val);}}public int getMaxXorWithLimit(int val, int limit) {Trie node = this;if (node.min > limit) {return -1;}int ans = 0;for (int i = L - 1; i >= 0; --i) {int bit = (val >> i) & 1;if (node.children[bit ^ 1] != null && node.children[bit ^ 1].min <= limit) {ans |= 1 << i;bit ^= 1;}node = node.children[bit];}return ans;}}
