LeetCode_前缀树_贪心算法_中等_421.数组中两个数的最大异或值

妖狐艹你老母 2023-10-06 23:53 63阅读 0赞

目录

  • 1.题目
  • 2.思路
  • 3.代码实现(Java)

1.题目

给你一个整数数组 nums ,返回 nums[i] XOR nums[j] 的最大运算结果,其中 0 ≤ i ≤ j < n。

示例 1:
输入:nums = [3,10,5,25,2,8]
输出:28
解释:最大运算结果是 5 XOR 25 = 28.

示例 2:
输入:nums = [14,70,53,83,49,91,36,80,92,51,66,70]
输出:127

提示:
1 <= nums.length <= 2 * 105
0 <= nums[i] <= 231 - 1

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-xor-of-two-numbers-in-an-array

2.思路

(1)暴力穷举法
暴力穷举法比较容易想到,即使用 2 层 for 循环来枚举所有 nums[i] XOR nums[j] 的结果,并且在枚举过程中使用变量 res 来记录最大值。不过该方法的时间复杂度较高,为 O(n2),在 LeetCode 中提交时会出现“超出时间限制”的提示!

(2)前缀树 & 贪心
思路参考该 LeetCode 用户题解。

3.代码实现(Java)

  1. //思路1————暴力穷举法
  2. class Solution {
  3. public int findMaximumXOR(int[] nums) {
  4. int length = nums.length;
  5. int res = Integer.MIN_VALUE;
  6. for (int i = 0; i < length; i++) {
  7. for (int j = i; j < length; j++) {
  8. res = Math.max(res, nums[i] ^ nums[j]);
  9. }
  10. }
  11. return res;
  12. }
  13. }
  14. //思路2————前缀树 & 贪心
  15. class Solution {
  16. class Node {
  17. Node[] ns = new Node[2];
  18. }
  19. //初始化字典树的根节点
  20. Node root = new Node();
  21. //将 x 添加到字典树中
  22. public void add(int x) {
  23. Node p = root;
  24. for (int i = 31; i >= 0; i--) {
  25. //获取 x 的二进制表示的第 i 位(从左往右,依次是第 31 位、30位、...、0位)
  26. int u = (x >> i) & 1;
  27. if (p.ns[u] == null) {
  28. p.ns[u] = new Node();
  29. }
  30. p = p.ns[u];
  31. }
  32. }
  33. //获取字典树中与 x 的异或结果最大的数
  34. public int getVal(int x) {
  35. int res = 0;
  36. Node p = root;
  37. /*
  38. 采用如下贪心策略:对于 x 而言,可以从其二进制表示中的最高位开始往低位找,
  39. 尽量让每一位的异或结果为 1,这样找到的 res 与 x 的异或结果才是最大的。
  40. */
  41. for (int i = 31; i >= 0; i--) {
  42. //获取 x 的二进制表示的第 i 位
  43. int a = (x >> i) & 1;
  44. //获取 x 的二进制表示的第 i 位的相反位
  45. int b = 1 - a;
  46. if (p.ns[b] != null) {
  47. res |= (b << i);
  48. p = p.ns[b];
  49. } else {
  50. res |= (a << i);
  51. p = p.ns[a];
  52. }
  53. }
  54. return res;
  55. }
  56. public int findMaximumXOR(int[] nums) {
  57. int res = 0;
  58. for (int num : nums) {
  59. add(num);
  60. int j = getVal(num);
  61. res = Math.max(res, num ^ j);
  62. }
  63. return res;
  64. }
  65. }

发表评论

表情:
评论列表 (有 0 条评论,63人围观)

还没有评论,来说两句吧...

相关阅读