import java.util.*;
/**
* NC378 两数最大异或值
* @author d3y1
*/
public class Solution {
// 最高数位为30(0-30) -> 31位+1位符号位=32位
private final int HIGH_BIT = 30;
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 相似 -> ZJ26 异或 [nowcoder]
*
* @param array int整型一维数组
* @return int整型
*/
public int maxXOR (ArrayList<Integer> array) {
// return solution1(array);
// return solution11(array);
return solution2(array);
// return solution3(array);
// return solution33(array);
}
/**
* 位运算: 异或
*
* 双重循环遍历
*
* @param array
* @return
*/
private int solution1(ArrayList<Integer> array){
int n = array.size();
int max = 0;
int xor;
for(int i=0; i<n; i++){
for(int j=i+1; j<n; j++){
xor = array.get(i)^array.get(j);
max = Math.max(max, xor);
}
}
return max;
}
/**
* 位运算: 异或
*
* 双重循环遍历(哈希优化)
*
* @param array
* @return
*/
private int solution11(ArrayList<Integer> array){
HashSet<Integer> set = new HashSet<>();
for(int val: array){
set.add(val);
}
ArrayList<Integer> distinct = new ArrayList<>(set);
int size = distinct.size();
int max = 0;
int xor;
for(int i=0; i<size; i++){
for(int j=i+1; j<size; j++){
xor = array.get(i)^array.get(j);
max = Math.max(max, xor);
}
}
return max;
}
/**
* 位运算 + 哈希
*
* pre_k() 表示从最高位(第30位)开始的前k位
* a_i a_j 表示某两个选择的数
* xor 表示最终异或结果(从高位到低位,依次确定,优先置1)
*
* pre_k(xor) = pre_k(a_i) ^ pre_k(a_j)
* => pre_k(a_j) = pre_k(xor) ^ pre_k(a_i)
*
* xor当前数位优先置1, pre_k(xor)为已知
* 因此我们先将所有的pre_k(a_j)加入哈希表existed中, 再枚举校验是否存在某个数a_i, 使得pre_k(xor)^pre_k(a_i)恰好出现在existed中.
*
* 如果可以找到上面的a_i, 则当前数位可以为1, 否则当前数位只能为0.
*
* @param array
* @return
*/
private int solution2(ArrayList<Integer> array){
int xor = 0;
HashSet<Integer> existed = new HashSet<>();
// 从高位到低位 依次确定
for(int i=HIGH_BIT; i>=0; i--){
existed.clear();
for(int val: array){
// pre_k(a_j) val前k位 k=HIGH_BIT-i+1
existed.add(val>>i);
}
// 当前数位优先置1, 此处xor即pre_k(xor) k=HIGH_BIT-i+1
// xor = xor*2+1;
xor = (xor<<1)+1;
boolean found = false;
for(int val: array){
// 表示当前数位可以为1 <- 校验pre_k(xor)^pre_k(a_i)
if(existed.contains(xor^(val>>i))){
found = true;
break;
}
}
// 未找到 -> 表示当前数位不可为1, 减1置0
if(!found){
xor = xor-1;
}
}
return xor;
}
/**
* 字典树
* @param array
* @return
*/
private int solution3(ArrayList<Integer> array){
Trie trie = new Trie();
HashSet<Integer> set = new HashSet<>();
for(int val: array){
if(!set.contains(val)){
set.add(val);
trie.insert(val);
}
}
int max = 0;
int xor;
for(int val: set){
xor = trie.query(val);
max = Math.max(max, xor);
}
return max;
}
/**
* 字典树: 优化
* @param array
* @return
*/
private int solution33(ArrayList<Integer> array){
Trie trie = new Trie();
HashSet<Integer> set = new HashSet<>();
int max = 0;
int xor;
for(int val: array){
if(!set.contains(val)){
set.add(val);
trie.insert(val);
xor = trie.query(val);
max = Math.max(max, xor);
}
}
return max;
}
/**
* 字典树 Trie
*/
private class Trie {
Trie[] child = new Trie[2];
/**
* 新增
* @param val
*/
private void insert(int val){
Trie curr = this;
for(int j=HIGH_BIT; j>=0; j--){
int bit = (val>>j)&1;
if(curr.child[bit] == null){
curr.child[bit] = new Trie();
}
curr = curr.child[bit];
}
}
/**
* 查询: 获取当前数val的最大异或值
* @param val
* @return
*/
private int query(int val){
Trie curr = this;
int xor = 0;
for(int j=HIGH_BIT; j>=0; j--){
int bit = (val>>j)&1;
if(curr.child[bit^1] != null){
xor |= (1<<j);
curr = curr.child[bit^1];
}else{
curr = curr.child[bit];
}
}
return xor;
}
}
}