剑指offer37--找出数组中只出现1次的两个数

来源:互联网 发布:手机主板检测软件 编辑:程序博客网 时间:2024/05/18 02:51

一、题目


题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)


二、举例



例如输入数组{2, 4, 3, 6, 3, 2, 5 },因为只有4 、6 这两个数字只出现一次,其他数字都出现了两次,所以输出4和6



三、思想



1. 首先数组中所有元素依次异或,因为相同的元素异或得到0,所以最终的答案就等于那2个唯一的元素a^b的值。

2. 因为a,b不同,所以异或得到的答案肯定是不等于0的,那么我们就找到a^b的二进制表示中第一个为1的位,
假如是第k位。而a,b
两个数在第k位上是不同的,一个为0,一个为1

3. 接下来我们将第k位是1的分成一组,第k位是0的分成一组,如果2个元素相同,那么他们第k位肯定是一样的,所以肯定被分到同一组中。而a,b则被分到2组中去了。然后我们就可以在每个分组中异或每一个元素,最终就可以得到那2个唯一的元素。


四、程序




package 剑指offer;public class Test40 {    public static int[] findNumbersAppearanceOnce(int[] data) {        int[] result = {0, 0};                // 边界情况判断        if (data == null || data.length < 2) {            return result;        }        int xor = 0;        // 遍历数组data,大括号中的i就相当于data[i]        for (int i : data) {            xor ^= i;        }                // 找到所有数据异或结果中第一个不为零的数据位        int indexOf1 = findFirstBit1(xor);        // 遍历,通过判断indexOf1位是不是1将数组分成两组        for (int i : data) {        // 将是1的一组相互异或            if (isBit1(i, indexOf1)) {                result[0] ^= i;            } else {            // 将不是1的一组相互异或                result[1] ^= i;            }        }        return result;    }    private static int findFirstBit1(int num) {        int index = 0;        while ((num & 1) == 0 && index < 32) {            num >>>= 1;            index++;        }        return index;    }    private static boolean isBit1(int num, int indexBit) {        num >>>= indexBit;        return (num & 1) == 1;    }    public static void main(String[] args) {        int[] data1 = {2, 4, 3, 6, 3, 2, 5, 5};        int[] result1 = findNumbersAppearanceOnce(data1);        System.out.println(result1[0] + " " + result1[1]);    }


、收获


1、了解for(i :data){ i }的使用方式,其中大括号中i代表的是data[i]
2、异或是指位之间的异或,巧妙地使用异或来分组,还有>>>=代表的是位的右移,左边补充0

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 qq好友申诉后怎么办 无好友辅助申请怎么办 辅助申诉成功后怎么办 qq绑不了手机号怎么办 新办号码有微信怎么办 两手机互换号后微信怎么办 手机申请不了qq怎么办 快手账号保护了怎么办 qq号过期登不上怎么办 xp 登陆界面不见了怎么办 手机号qq 别人登录怎么办 qq号申请频繁怎么办 qq号实名验证怎么办 陌陌没法注册怎么办 腾讯q币充值错误怎么办 手机号码注册微信号怎么办 q币充错了号怎么办 微信超额度提现都不可以怎么办 微信发红包转账限额怎么办 银行卡没设密码怎么办 宜人贷逾期一天怎么办 快手实名已认证怎么办 爱奇艺充会员没有银行卡怎么办 手机qq内存太大怎么办 借呗逾期半年怎么办 支付宝支付错误怎么办 小米6支付宝闪退怎么办 验证码发送失败怎么办 支付宝升级后打不开怎么办 steam支付宝失败怎么办 支付宝无响应怎么办 花呗加载失败怎么办 吃鸡平台无效怎么办 悦支付登录不了怎么办 微信里的钱超额怎么办 qq不能发红包怎么办 qq红包多发了怎么办 qq红包领不了怎么办 qq红包密码忘记怎么办 钱包锁密码忘记怎么办 支付宝红包过期怎么办