面试题:找出数组中唯一一个未重复的数(找出二个不同的未重复的数据)

1、找出数组中唯一一个未重复的数

异或:一个数异或它本身等于0

   public static int NumberOf1(int[] arr) {
        int len = arr.length;
        int res = -1;
        if(len > 1) {
            res = arr[0];
            for (int i = 1; i < len; i++) {
                res = res ^ arr[i];//异或处理
            }
        }
        System.out.println(res);
        return res;
    }

时间复杂度为O(N)

空间复杂度为O(1)

 2、不重复的数字有两个

解决办法:

1、先遍历一遍数组,异或得到一个数N,这个数就是只出现一次的那两个数异或的结果,

2、然后找到N最低为1的位(假设是J位),

3、再次遍历数组,按倒数第J位为1和为0将数组分为两个数组,此时只出现一次的两个数就被分到了不同的组,然后对每个组按照1的方法找出来就可以了。

    public static void main(String[] args) {
        Integer[] ints = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 17};
        // 异或结果
        int n = NumberOf1(ints);
        // 记录右移次数
        int j = 0;
        while ((n & 1) != 1) {
            n = n >> 1;
            j++;
        }
        System.out.println("异或结果" + n);
        System.out.println("右移位数" + j);

        // 这两个数据 保存结果
        int[] result = new int[2];

        // 倒数最j位为1的集合
        List<Integer> int1 = new LinkedList<>();
        // 倒数最j位为0的集合
        List<Integer> int2 = new LinkedList<>();
        for (int i = 0; i < ints.length; i++) {
             if ((1 & ints[i] >> j) == 1) {
                 int1.add(ints[i]);
                 // 直接异或
                 result[0]^=(ints[i]);
             } else {
                 int2.add(ints[i]);
                 // 直接异或
                 result[1]^=(ints[i]);
             }
        }
        System.out.println("倒数最j位为1的集合" + int1);
        System.out.println("倒数最j位为0的集合" + int2);

        System.out.println("结果集合" + Arrays.toString(result));
    }

    
    public static int NumberOf1(Integer[] arr) {
        int len = arr.length;
        int res = -1;
        if(len > 1) {
            res = arr[0];
            for (int i = 1; i < len; i++) {
                //异或处理
                res = res ^ arr[i];
            }
        }
        return res;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值