剑指offer40_数组中只出现一次的数字_题解

数组中只出现一次的数字

题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

分析

方案一:分组异或

先对所有数字进行一次异或,得到两个出现一次的数字的异或值。

在异或结果中找到任意为 1 的位。

根据这一位将所有的数字分成两组。

在每个组内进行异或操作,得到两个数字。

代码

/**
1.时间复杂度:O(n)
只需要遍历数组两次。
2.空间复杂度:O(1)
只需要常数的空间存放若干变量。
**/
class Solution
{
public:
    void FindNumsAppearOnce(vector<int> data, int *num1, int *num2)
    {
        int ret = 0;
        for (int n : data)
            ret ^= n;
        int div = 1;
        while ((div & ret) == 0)
            div <<= 1;
        int a = 0, b = 0;
        for (int n : data)
        {
            if (div & n)
                a ^= n;
            else
                b ^= n;
        }
        *num1 = a, *num2 = b;
    }
};

方案二:哈希

第一次遍历用一个哈希数组存储每个数字是否重复出现,为真没有重复出现,为假则重复出现

第二次遍历判断哈希数组值是否为真,为真则为所求数字,加入结果集合

代码

/**
1.时间复杂度:O(n)
2.空间复杂度:O(n)
**/
class Solution
{
public:
    void FindNumsAppearOnce(vector<int> data, int *num1, int *num2)
    {
        map<int, bool> dic;
        for (int k : data)
        {
            dic[k] = dic.find(k) == dic.end();
        }
        int cnt = 1;
        for (int k : data)
        {
            if (dic[k])
            {
                if (cnt == 1)
                {
                    *num1 = k;
                }
                if (cnt == 2)
                {
                    *num2 = k;
                }
                ++cnt;
            }
        }
    }
};
posted @ 2021-01-14 16:41  RiverCold  阅读(56)  评论(0编辑  收藏  举报