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

题目:给一个数组,数组里面有相同的元素,有不同的元素,每组相同的元素刚好有两个,不同的元素也是刚好两个

思路:1,之前没认真看题目的条件,导致写了一套通用的,不管相同元素有多少个,代码优化之如下:

public int[] singleNumber(int[] nums) {

  int len = nums.length;
  Map<Integer,Integer> countMap = new HashMap<Integer,Integer>();
  for(int i = 0;i<len;i++){
    Integer count = countMap.get(nums[i]);
    if(count==null){
      countMap.put(nums[i],1);
    }else{
      countMap.put(nums[i],count+1);
    }
  }

  int[] res = new int[2];
  int i = 0;
  for(Entry e :countMap.entrySet()){
    if((Integer)e.getValue()==1){
      res[i++] = (Integer)e.getKey();
    }
}
return res;

}

更符合题意的思路2:

思路2主要是根据逻辑位运算的特点:因为题意是每一组相同元素的个数只有两个,那么我们只要把它们异或XOR运算一下,就为0了,将数组所有的数逐一进行异或运算,最后得到的就是两个不同的元素的异或的结果,可以根据这个结果取其二进制形式中的某一位1,为什么去1呢,因为异或运算就是相同为0,不同为1,这个可以区分的是两个不同数,区分出来了,over。。。

public int[] singleNumber(int[] nums) {

  int distinct = 0,len = nums.length;

  for(int i = 0;i <len;i++){

    distinct ^= nums[i];

  }

  distinct &=-distinct;

  int res [] = new int[2];

  for(int i = 0;i<len;i++){

    if((res&nums[i])==0){

      res[0] ^=nums[i];

    }else{

      res[1]^=nums[i];

    }

  }

  return res;

}

runtime居然2ms,比我之前那个是快多了,说实话,这个道题让我感觉到了编程的快乐

posted @ 2016-07-15 17:05  Roger's  阅读(132)  评论(0编辑  收藏  举报