Acwing---143. 最大异或对

最大异或对

1.题目

在给定的 N个整数 A1,A2......AN 中选出两个进行 xor(异或)运算,得到的结果最大是多少?

输入格式

第一行输入一个整数 N。

第二行输入 N 个整数 A1~AN。

输出格式

输出一个整数表示答案。

数据范围
1 ≤ N ≤ 1 0 5 , 1≤N≤10^5, 1≤N≤105,

0 0 0≤ A i Ai Ai<2^31

输入样例:

3

1 2 3

输出样例:

3

2.基本思想

  • 1.son数组定义是二维数组,son[n][m],可以先理解它的第二维度,只有两种状态0/1,是因为这一位表示的是某个数字的的某一位是0 / 1,而第一维的大小是我们用的十位二进制表示下一共有多少位数,在本题中,数字一共有N个数字,N是小于10^5的,一个数在int下是32位,则我们需要至多3200000的一维坐标,而p = son[n][0] / p = son[n][1]其实存的值就是他的两个子节点的一维坐标的值。

    那么x >> i & 1 其实就是我想知道x的二进制表示中的第i位(二进制位从第0位开始表示第0位 - 第 31 位),本题的题目范围到2^31那么就是i从30 - 0

  • 2.构建逻辑其实相对简单,就是将数的二进制表示插入到son数组中,如果没有那么就将他的值附上++idx即可

  • 3.查询的时候为了异或大小最大,那么就应该从根节点开始遍历最高位开始尽量让异或结果为1,在遍历查询数字的第i位的时候取第i位的值为s,查看son[p][!s]是否存在,如果存在那么将res+= i << i(这一位异或存在最大值为1),如果没有那么就让p = son[p][s]

3.代码实现

csharp 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Main {
    static int N = 3000010;
    static int[][] son = new int[N][2];
    static int idx;
    static int[] a = new int[N];

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
            insert(a[i]);
        }

        int res = 0;
        for (int i = 0; i < n; i++) res = Math.max(res, query(a[i]));
        System.out.println(res);
    }

    private static void insert(int x) {
        int p = 0;
        for (int i = 30; i >= 0; i--) {//从30开始枚举
            int s = son[p][(x >> i) & 1];//看 x的二进制表示中 个位 是 0 还是 1
            if (s == 0) son[p][(x >> i) & 1] = ++idx;//创建新节点
            p = son[p][(x >> i)&1];
        }
    }

    private static int query(int x) {
        int res = 0, p = 0;
        for (int i = 30; i >= 0; i--) {//从30开始枚举
            int s = (x >> i) & 1;//看 x的二进制表示中 个位 是 0 还是 1
            if (son[p][1 - s] != 0) {
                res += (1 << i);
                p = son[p][1 - s];
            } else p = son[p][s];
        }
        return res;
    }
}
相关推荐
贫民窟的勇敢爷们4 小时前
SpringBoot整合AOP切面编程实战,实现日志统一记录+接口权限校验
java·spring boot·spring
浅念-4 小时前
递归解题指南:LeetCode经典题全解析
数据结构·算法·leetcode·职场和发展·排序算法·深度优先·递归
Kiling_07044 小时前
Java集合进阶:Set与Collections详解
算法·哈希算法
AC赳赳老秦4 小时前
供应链专员提效:OpenClaw自动跟踪物流信息、更新库存数据,异常自动提醒
java·大数据·服务器·数据库·人工智能·自动化·openclaw
迈巴赫车主4 小时前
Java基础:list、set、map一遍过
java·开发语言
智者知已应修善业5 小时前
【51单片机89C51及74LS273、74LS244组成】2022-5-28
c++·经验分享·笔记·算法·51单片机
灵犀学长5 小时前
基于 Spring ThreadPoolTaskScheduler + CronTrigger 实现的动态定时任务调度系统
java·数据库·spring
洛水水5 小时前
【力扣100题】33.验证二叉搜索树
算法·leetcode·职场和发展
SimpleLearingAI5 小时前
聚类算法详解
算法·数据挖掘·聚类
刀法如飞6 小时前
Go 字符串查找的 20 种实现方式,用不同思路解决问题
算法·面试·程序员