LeetCode 136. Single Number

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

题意:给定一个整型数组,数组中除了一个数字外,其余数字都出现两次,找到只出现一次的数字。
Note:
要求算法的时间复杂度为O(n),空间复杂度为O(1)。

开始想到了使用排序和使用set的方法,但都不同时满足时间复杂度和空间复杂度的要求。

思路1:先对数组排序,
如果nums[i] == nums[i + 1],则下标i直接加2,跳过这两个数;否则nums[i]为只出现一次的元素。

public int singleNumber(int[] nums) {
        Arrays.sort(nums);
        int len = nums.length;
        int i = 0;
        while(i < len - 1){
            if(nums[i] == nums[i + 1])
                i = i + 2;
            else
                return nums[i];
        }
        return nums[len - 1];
    }

思路2:1. 利用set不包含重复元素的特性。
2. 设数组元素为{a, a, c},则(a + c) * 2 - (a + a + c) = c
将数组中不重复的元素都存入set,并计算所有不重复元素的和sum1;再利用sum1与数组元素总和sum2的关系。

public int singleNumber(int[] nums) {
        int len = nums.length;
        Set set = new HashSet();
        int sum1 = 0, sum2 = 0;
        for(int i = 0; i < len; i++){
            sum2 += nums[i];
            if(!set.contains(nums[i])){
                set.add(nums[i]);
                sum1 += nums[i] * 2;
            }
        }
        return sum1 - sum2;
    }

思路3:看了LeetCode提供的答案,才知道用异或的方法。
异或的运算规则:仅当对应位的两个数不相同时,结果才为1;否则为0。即位相同(0,0或1,1)时,结果为0,位不同时(0,1或1,0)结果为1。
所以,0异或任何数A,结果还是A
由于数字在计算机是以二进制存储的,每位上都是0或1。
因此对数组中所有元素进行异或,则每对相同的数字都会得0,最后剩下的数字就是只出现一次1次的数字。

public int singleNumber(int[] nums) {
        int a = 0;
        for(int num : nums){
            a ^= num;
        }
        return a;
    }

 

posted @ 2018-03-03 13:19  zeroingToOne  阅读(107)  评论(0编辑  收藏  举报