给定一个整数数组nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次,找出只出现一次的那两个元素。时间复杂度要求为O(n),空间为O(1);

自己的做法
public static int[] singleNumber(int[] nums) {
  HashSet<Integer> set = new HashSet<>();
  for (int num: nums) {
      if (set.contains(num)) {
          set.remove(num);
      } else {
          set.add(num);
      }
  }
  int[] result = new int[2];
  int i = 0;
  for (int n : set) {
      result[i++] = n;
  }
  return result;
}
位运算
public static int[] singleNumber1(int[] nums) {
    /*
     * 这个题目使用位运算很合适,主要是异或计算符
     * 1、任何数与0异或,结果都是原来的数
     * 2、任何数与自身异或,结果为0
     * */
    int all = 0;
    for (int num : nums) {
        all ^= num;
    }
    //因为all是两个只出现一次的数字异或的结果,所以找到最低位为1的,作为分界点,
    //为1说明这两个数字在这个位上 一个是0,一个是1,那么用这个第i位去分组,为0的在一组,为1的在另外一组
    //这样在两个组里面分别找出来两个不同的数字
    int div = 1;
    while ((div & all) == 0) {
        div <<= 1;
    }
    int a = 0, b = 0;
    for (int n : nums) {
        if ((div & n) != 0) {
            a ^= n;
        } else {
            b ^= n;
        }
    }
    return new int[]{a, b};
}