Leetcode--136. 只出现一次的数字

Posted on 2020-03-21 10:50  南望96X  阅读(85)  评论(0)    收藏  举报

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4

方法1:泛型算法暴力解决
代码:
class Solution1
{
public:
    int singleNumber(vector<int> &nums)
    {
        for (auto it = nums.begin(); it != nums.end(); it++)
            if (count(nums.begin(), nums.end(), *it) == 1)  //使用泛型算法的count
                return *it;
        return 0;
    }
}; 

方法2:循环暴力解决

代码:

class Solution2
{
public:
    int singleNumber(vector<int> &nums)
    {
        int i, j, cur;
        int len = nums.size();
        for (i = 0; i < len; i++)
        {
            cur = nums[i];
            for (j = 0; j < len; j++) //寻找数组后面是否存在相同数字
            {
                if (j == i)
                    continue;
                if (cur == nums[j])
                    break;
            }
            if (j == len)
                return cur;
        }
        return -1;
    }
};

以上两种方法是常规做法,很容易想到,但不满足题目的线性时间复杂度

方法3:位异或运算符

异或:相同的二进制位进行位异或之后结为0,不同的二进制位进行位异或后结果为1

1. a ⊕ a = 0
2. a ⊕ b = b ⊕ a
3. a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;
4. d = a ⊕ b ⊕ c 可以推出 a = d ⊕ b ⊕ c.
5. a ⊕ b ⊕ a = b.

a⊕0=a,

a⊕a=0,

a⊕b⊕a=(a⊕a)⊕b=0⊕b=b

因此可以将每个数都进行位异或运算,最后得到的数就是只出现一次的数

class Solution3{
public:
    int singleNumber(vector<int> &nums){
        int num=0;
        for(int i=0;i<nums.size();i++)
            num^=nums[i];
        return num;
    }
};

时间复杂度为O(n),只需要遍历一次数组,空间复杂度为O(1)