题解 | #数组中只出现一次的两个数字#

数组中只出现一次的两个数字

http://www.nowcoder.com/practice/389fc1c3d3be4479a154f63f495abff8

import java.util.*;

*
其实这个题的关键就在于怎么分离第一次异或之后所得的a^b
首先要知道,a和b不是同一个数,那么异或结果不为0,那么结果的二进制肯定至少有一个是1
也就是说,为1的这一位上,a和b的二进制一个是0,一个是1
只要我们下一次异或只把是0(或者是1)的异或进来,出现两次还是会异或为0,不影响,剩下的就是a或者b
取一个不为0的数二进制最右边的1是固定的写法。自己与上自己取反加1的值,取反加1在括号里
搞出来一个a或者b了,再和一开始的a^b异或在一起,得到另外一个数
最后三元运算符得到两个数中较小的一个,放在前面就可以了。

*

public class Solution {
    public int[] FindNumsAppearOnce (int[] array) {
        int eor = 0;//任何数和0异或都等于它本身
        for(int i = 0;i < array.length;i++){
            eor ^= array[i];//这样结束了就是两个不一样的数相异或
        }
        int eor2 = 0;//再搞一个eor
        int rightOne = eor & (~eor + 1);//固定写法,一个不为0的数最右边的1就这么求
        //自己与上自己取反加1的值就是最右边的一个1
        for(int j = 0;j < array.length;j++){
            if((array[j] & rightOne) == 0){//如果某个数在这一位上面是1,相与结果才是1,注意优先级
                eor2^=array[j];//这样异或下来eor2就是其中一个数
            }
        }
        int a = eor2;
        int b = eor^eor2;
        return a < b ? new int[]{a, b} : new int[]{b, a};
    }
}
全部评论

相关推荐

7 收藏 评论
分享
牛客网
牛客企业服务