260. Single Number III

来源:互联网 发布:js 数组比较相同 编辑:程序博客网 时间:2024/04/25 21:08

问题描述:

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].

给定一个数组,该数组中有两个数只出现一次而其他数都刚好出现两次,找到这两个数并返回一个含有这两个数的数组,顺序不care。

方法一:

使用java的集合类set,遍历数组,对于每一个数字,若集合中没有则放入其中;若有则将其从集合中移除。

public class Solution {    public int[] singleNumber(int[] nums) {        Set<Integer> set = new HashSet<Integer>();        for(int i=0;i<nums.length;i++){            if(set.contains(nums[i])){                set.remove(nums[i]);            }            else{                set.add(nums[i]);            }        }        Object[] res;        res = set.toArray();        int[] result = {(int)res[0],(int)res[1]};        return result;    }}


方法二:

可以考虑将所有的数按位异或,便得到所求两个数按位异或的结果。这里使用了一个非常巧妙的方法将两者分开,我们注意到由于这两个数是肯定不相等的,那么在异或运算之后结果的比特位肯定会有1的情况,这是表示这两个数在该比特位一个是0,一个是1。恰恰我们可以利用这一点,将两者分开!我们假设这个比特位是第k位。

  此时,我们可以再次遍历数组,将元素中第k比特位为0和1的分开成两队单独进行异或运算。这样一来,我们不仅保证了两队中都会有一个最后的独数,而且还确保了这两个队列中有且仅有这个数是单独的,其余元素仍然是成对出现。所以,这两组队列分别进行异或运算之后的结果就是我们想要的答案。

public class Solution {      public int[] singleNumber(int[] nums) {          int[] result = new int[2];          int temp = 0;          for(int i = 0; i < nums.length; i++)              temp ^= nums[i];          int j = 1;          while((temp & j) != j)              j <<= 1;          for(int i = 0; i < nums.length; i++) {              if((nums[i] & j) == j)                  result[0] ^= nums[i];              else                  result[1] ^= nums[i];          }          return result;      }  }




0 0