题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。你可以不使用额外空间来实现吗?
示例1
输入: [2,2,1]
输出: 1示例2
输入: [4,1,2,1,2]
输出: 4题解
方法1:利用Set集合元素不重复
创建一个Set数组,将nums数组的元素一个一个的插入set,成插入说明不重复,插入不成功说明是重复的。
class Solution {
    public int singleNumber(int[] nums) {
        Set<Integer> set = new HashSet<Integer>();
        for(int num : nums){
            if(!set.add(num)){
                set.remove(num);
            }
        }
        return (int)set.toArray()[0];
    }
}方法2:数组先排序,再遍历
题目说明了一个数字出现了1次,其他数字都出现了2次,所以数组的长度一定是个奇数。每次比较两个,循环步长设为2,分析一下单独数字出现的情况。

先对数组进行排序,从index=0开始,比较相邻的元素值,循环步长设为2,如果出现nums[i]和nums[i+1]不相等,那么nums[i]是出现一次的数字;如果全都相等,那么最后一个是单独出现的数字。
class Solution {
    public int singleNumber(int[] nums) {
        Arrays.sort(nums);
        for(int i=0; i<nums.length-1; i+=2){
            if(nums[i] != nums[i+1]){
                return nums[i];
            } 
        }
        return nums[nums.length-1];
    }
}方法3:利用位运算
题目强调只有一个数字出现了1次,其他数字都出现了2次。我们可以利用异或运算进行解题。
在计算机中异或运算拥有以下特征
- 0 ^ 0 = 0 
- 1 ^ 0 = 1 
- 0 ^ 1 = 1 
- 1 ^ 1 = 0
因此,我们可以推出以下结论
- 归零律:a ^ a = 0
- 恒等律:a ^ 0 = a
- 交换律:a ^ b ^ c = a ^ c ^ b 
也就是说,一个数(转成二进制),自己异或自己是0;同时任何数异或0都得他本身。
class Solution {
    public int singleNumber(int[] nums) {
    int res = 0;
        for (int num : nums) {
            res = res ^ num;
        }
        return res;
    }
}甚至可以省略一个变量,直接用数组第一个元素。
class Solution {
    public int singleNumber(int[] nums) {
        for(int i=1; i<nums.length; i++){  //从下标=1开始
            nums[0] ^ = nums[i];
        }
        return nums[0];
    }
}// End //










