1707.与数组中元素的最大异或值

题目描述:

image.png


解:

421.数组中两个数的最大异或值的进阶版
此题也是求最大的异或值,同样需要构造一个01字典树。有区别的是:

  1. 采取离线查询的方法:每次将需要参加筛选的值加入到字典树
  2. 采取在线查询的方法:一次性将数组所有值加入字典树,再对于每一个查询的值进行判断。

以下代码是抄官解的:
1.离线查询:

  1. class Solution {
  2. public int[] maximizeXor(int[] nums, int[][] queries) {
  3. Arrays.sort(nums);
  4. int numQ = queries.length;
  5. int[][] newQueries = new int[numQ][3];
  6. for (int i = 0; i < numQ; ++i) {
  7. newQueries[i][0] = queries[i][0];
  8. newQueries[i][1] = queries[i][1];
  9. newQueries[i][2] = i;
  10. }
  11. Arrays.sort(newQueries, new Comparator<int[]>() {
  12. public int compare(int[] query1, int[] query2) {
  13. return query1[1] - query2[1];
  14. }
  15. });
  16. int[] ans = new int[numQ];
  17. Trie trie = new Trie();
  18. int idx = 0, n = nums.length;
  19. for (int[] query : newQueries) {
  20. int x = query[0], m = query[1], qid = query[2];
  21. while (idx < n && nums[idx] <= m) {
  22. trie.insert(nums[idx]);
  23. ++idx;
  24. }
  25. if (idx == 0) { // 字典树为空
  26. ans[qid] = -1;
  27. } else {
  28. ans[qid] = trie.getMaxXor(x);
  29. }
  30. }
  31. return ans;
  32. }
  33. }
  34. class Trie {
  35. static final int L = 30;
  36. Trie[] children = new Trie[2];
  37. public void insert(int val) {
  38. Trie node = this;
  39. for (int i = L - 1; i >= 0; --i) {
  40. int bit = (val >> i) & 1;
  41. if (node.children[bit] == null) {
  42. node.children[bit] = new Trie();
  43. }
  44. node = node.children[bit];
  45. }
  46. }
  47. public int getMaxXor(int val) {
  48. int ans = 0;
  49. Trie node = this;
  50. for (int i = L - 1; i >= 0; --i) {
  51. int bit = (val >> i) & 1;
  52. if (node.children[bit ^ 1] != null) {
  53. ans |= 1 << i;
  54. bit ^= 1;
  55. }
  56. node = node.children[bit];
  57. }
  58. return ans;
  59. }
  60. }

2.在线查询

  1. class Solution {
  2. public int[] maximizeXor(int[] nums, int[][] queries) {
  3. Trie trie = new Trie();
  4. for (int val : nums) {
  5. trie.insert(val);
  6. }
  7. int numQ = queries.length;
  8. int[] ans = new int[numQ];
  9. for (int i = 0; i < numQ; ++i) {
  10. ans[i] = trie.getMaxXorWithLimit(queries[i][0], queries[i][1]);
  11. }
  12. return ans;
  13. }
  14. }
  15. class Trie {
  16. static final int L = 30;
  17. Trie[] children = new Trie[2];
  18. int min = Integer.MAX_VALUE;
  19. public void insert(int val) {
  20. Trie node = this;
  21. node.min = Math.min(node.min, val);
  22. for (int i = L - 1; i >= 0; --i) {
  23. int bit = (val >> i) & 1;
  24. if (node.children[bit] == null) {
  25. node.children[bit] = new Trie();
  26. }
  27. node = node.children[bit];
  28. node.min = Math.min(node.min, val);
  29. }
  30. }
  31. public int getMaxXorWithLimit(int val, int limit) {
  32. Trie node = this;
  33. if (node.min > limit) {
  34. return -1;
  35. }
  36. int ans = 0;
  37. for (int i = L - 1; i >= 0; --i) {
  38. int bit = (val >> i) & 1;
  39. if (node.children[bit ^ 1] != null && node.children[bit ^ 1].min <= limit) {
  40. ans |= 1 << i;
  41. bit ^= 1;
  42. }
  43. node = node.children[bit];
  44. }
  45. return ans;
  46. }
  47. }