[leetcode] Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

      对于一个数组只有一个数出现一次的,其他都出现2次,我们找出这个数很简单。利用异或运算的性质,即两个相同的数异或结果是0,把数组中所有的数都异或一遍,就可以直接得出这个单个的数。
      本题目相当于是对上述的扩展,利用上述的方法,我们很直观的就会想到因为有两个数只出现一次,那么是不是可以把这个数组分成两个部分,每个部分都形如上述问题中的数组,即只有一个是单个的,其余的都是两个的。
      那么主要的问题就是怎么分才能分成这样的数组。
      下面来看两个简单的异或的例子:
      111^100 = 011;
      010^011 = 001;
      再结合异或的计算方法,即相同的位的异或结果为0,不同的是1。可以很清楚的知道,如果一个位上的结果是1,那么肯定是由一个0和一个1异或得到的。也就是说这一位上必然有一个数是0,另一个是1。刚好就是我们的分组条件,即假设这一位的index = m,那么原来的数组就可以被分成两个部分,一个部分第m位是0,另一部分第m位是1。分完组之后,把两个数组分别异或出来的结果就是所求的结果。
java代码如下:

public int[] singleNumber2(int[] nums) {
        int[] value = new int[2];
        if (nums.length <= 2) {
            return nums;
        }
        int result = 0;
        for (int i = 0; i < nums.length; i++) {
            result ^= nums[i];
        }
        String hex = Long.toBinaryString(result);
        int x = 0;
        for (int i = hex.length() - 1; i >= 0; i--) {
            if (hex.charAt(i) == '1') {
                x = (int)Math.pow(2, hex.length() - 1 - i);
                break;
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if ((nums[i] & x) == x) {
                value[0] ^= nums[i];
            }else{
                value[1] ^= nums[i];
            }
        }
        return value;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值