421. Maximum XOR of Two Numbers in an Array

xiaoxiao2021-02-28  36

Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231.

Find the maximum result of ai XOR aj, where 0 ≤ i, j < n.

Could you do this in O(n) runtime?

Example:

Input: [3, 10, 5, 25, 2, 8] Output: 28 Explanation: The maximum result is 5 ^ 25 = 28.

题目要求O(n)时间复杂度。

因为处理位运算,可以尝试将十进制数转化为二进制数,而二进制数可通过0,1表示,因此可以尝试采用前缀树求解。

首先根据数组元素建立一颗前缀树,这里特别需要注意的一点是:树的深度为33,不是32,因为引入了一个跟节点。当访问nums[i]时,再深入看nums[i]的位信息,如果当前访问到j位,则判断:

1、如果j位只有一个儿子,则别无选择,不论子节点值为0还是1,只能继续往下走。

2、如果j位有两个儿子,说明从该处,至少有两个不同的数出现(含nums[i]),则可以选择与nums[i]在j位不同值的路线走下去

程序如下所示:

class Solution { class TrieNode{ public int val; public TrieNode left; public TrieNode right; public TrieNode(int val){ this.val = val; this.left = null; this.right = null; } } public int findMaximumXOR(int[] nums) { TrieNode root = createTrie(nums); TrieNode curNode = root; int max = 0; for (int i = 0; i < nums.length; ++ i){ curNode = root; int val = 0; for (int j = 31; j >= 0; -- j){ int tmp = nums[i] & (1 << j); if (curNode.left != null && curNode.right != null){ if (tmp == 0){ curNode = curNode.left; } else { curNode = curNode.right; } } else { curNode = curNode.left == null?curNode.right:curNode.left; } val |= (curNode.val << j); } max = Math.max(max, nums[i]^val); } return max; } public TrieNode createTrie(int[] nums){ TrieNode root = new TrieNode(0); TrieNode curNode = root; for (int i = 0; i < nums.length; ++ i){ for (int j = 31; j >= 0; -- j){ int tmp = nums[i] & (1 << j); if (tmp == 0){ if (curNode.right == null){ curNode.right = new TrieNode(0); } curNode = curNode.right; } else { if (curNode.left == null){ curNode.left = new TrieNode(1); } curNode = curNode.left; } } curNode = root; } return root; } }

转载请注明原文地址: https://www.6miu.com/read-2623387.html

最新回复(0)