题目描述:

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

思路分析:

1. 直接想法,每个数字遍历,统计出现次数,复杂度O(n^2),超时。

2. 借助哈希表,空间换时间,遍历一次,时间复杂度O(n),空间复杂度O(n),对于空间复杂度限制为O(1)时,不满足条件。

3. 利用异或运算。已知两个相同的数,异或为0。若当前的题目是只求一个只出现一次的数字时,只需要将数组中的数字都异或一次,最后得到的即为所求的只出现一次的数字。那么拓展到两个数字的情况,

我们可以将原始数组分成两个子数组,使得每个子数组包含一个只出现一次的数字,而其他数字都成对出现。这样,我们就可以用上述方法找到那个孤苦伶仃的元素。

我们还是从头到尾一次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数组的异或结果。因为其他数字都出现了两次,在异或中全部抵消了。由于两个数字肯定不一样,那么异或的结果肯定不为0,也就是说这个结果数组的二进制表示至少有一个位为1。我们在结果数组中找到第一个为1的位的位置,记为第n位。现在我们以第n位是不是1为标准把元数组中的数字分成两个子数组,第一个子数组中每个数字的第n位都是1,而第二个子数组中每个数字的第n位都是0。

举例:{2,4,3,6,3,2,5,5}

我们依次对数组中的每个数字做异或运行之后,得到的结果用二进制表示是0010。异或得到结果中的倒数第二位是1,于是我们根据数字的倒数第二位是不是1分为两个子数组。第一个子数组{2,3,6,3,2}中所有数字的倒数第二位都是1,而第二个子数组{4,5,5}中所有数字的倒数第二位都是0。接下来只要分别两个子数组求异或,就能找到第一个子数组中只出现一次的数字是6,而第二个子数组中只出现一次的数字是4。

代码:

思路二:

 class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
if(data.size()<=)
return;
map<int, int> data_map;
for(int i=; i<data.size(); i++)
{
data_map[data[i]]++;
}
vector<int> v;
for(int i=; i<data.size(); i++)
{
if(data_map[data[i]]==)
v.push_back(data[i]);
}
*num1 = v[];
*num2 = v[];
}
};

思路三:

class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int length = data.size();
if(length<)
return;
//对原始数组求异或
int resultExclusiveOR = ;
for(int i=; i<length; i++)
resultExclusiveOR ^= data[i]; unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
*num1 = ;
*num2 = ;
for(int j=; j<length; j++)
{
if(IsBit1(data[j], indexOf1))
{
*num1 ^= data[j];
}
else
{
*num2 ^= data[j];
}
}
}
private:
//找到二进制数num第一个为1的位数,如0010,第一个为1的位数是2
unsigned int FindFirstBitIs1(int num)
{
unsigned int indexBit = ;
//只判断一个字节的
while((num & )== && (indexBit < *sizeof(unsigned int)))
{
num = num >> ;
indexBit++;
}
return indexBit;
}
//判断第indexBit位是否为1
bool IsBit1(int num, unsigned int indexBit)
{
num = num >> indexBit;
return (num & );
}
};

剑指offer:数组中只出现一次的数字的更多相关文章

  1. 剑指Offer 数组中只出现一次的数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.   思路: 因为有2个数字只出现了一次,而其他的数字都是2次,可以通过异或运算,得到最后这2个只 ...

  2. 剑指Offer——数组中只出现一次的数字

    题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 数组中一共有偶数个数.两个数字只出现过一次. 相同数异或在一起等于0,那么将所有数异或 ...

  3. 剑指Offer——数组中只出现一次的数字(一个很帅的异或解法)

    题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 看题目脑子里就出现做法了: 遍历,用个HashMap来记录出现的次数,然后再遍历HashMap返回 ...

  4. 用java刷剑指offer(数组中只出现一次的数字)

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 牛客网链接 思路 链接:https://www.nowcoder.com/questionTer ...

  5. leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)

    136. Single Number 除了一个数字,其他数字都出现了两遍. 用亦或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1 2.与自己亦或为0,与0亦或为原来的数 class Solu ...

  6. 剑指Offer-40.数组中只出现一次的数字(C++/Java)

    题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 我们知道,两个相同的数字异或的结果等于0,所以利用这个性质将数组中所有的数字异或,求得的结 ...

  7. 剑指offer--35.数组中只出现一次的数字

    时间限制:1秒 空间限制:32768K 热度指数:198150 本题知识点: 数组 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. class ...

  8. 剑指 Offer —— 数组中重复的数字

    数组中的重复数字 题目描述 牛课网链接 长度为 n 的数组里,所有数字都在 0 到 n-1 的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一 ...

  9. 剑指offer 数组中重复的数

    在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{ ...

  10. 剑指offer——数组中出现次数超过一半的数字(c++)

    题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如 ...

随机推荐

  1. 如何统一管理单个任务下所有API的同步情况?

    如何统一管理单个任务下所有API的同步情况 1. 一分钟完成单个API配置 单个API的配置包含:API名称.URL地址.请求方式.参数设置.自定义高级设置. 参数允许用户填写:Text.WebSer ...

  2. java程序员常用的cmd命令

    1.查看端口号或者进程号使用情况 1.1.查看所有端口占用情况 C:\Users\Administrator>netstat -ano 活动连接 协议 本地地址 (ip:端口) 外部地址 状态 ...

  3. 使用Docker搭建Elasticsearch集群环境

    本篇文章首发于头条号单机如何搭建Elasticsearch集群?使用容器技术快速构建集群环境,欢迎关注头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_te ...

  4. MySQL主从复制什么原因会造成不一致,如何预防及解决?

    一.导致主从不一致的原因主要有: 人为原因导致从库与主库数据不一致(从库写入) 主从复制过程中,主库异常宕机 设置了ignore/do/rewrite等replication等规则 binlog非ro ...

  5. jQuery知识梳理20190818

    目录 jQuery知识梳理20190818 1. 时间绑定和解绑 2. 区别mouseover与mouseenter 3. 时间委托(委派/代理) 4 . 多库共存 5.window.onload与$ ...

  6. 使用ZeroClipboard 复制指定内容到剪切板

    有些时候,我们希望让用户在网页上完成某个操作就能自动将指定的内容复制到用户计算机的剪贴板中.但是出于安全原因,大多数现代浏览器都未提供通用的剪贴板复制接口(或即便有,也默认被禁用).只有IE浏览器可以 ...

  7. 流Stream的关闭

    文章;MemoryStream.Close() or MemoryStream.Dispose() Close() and Dispose(), when called on a MemoryStre ...

  8. 运维笔试Python编程题

    一.用Python语言把列表[1,3,5,7,9]倒序并将元素变为字符类型,请写出多种方法: 第一种方法: list = [1, 3, 5, 7, 9] list.reverse() list2 = ...

  9. P1856 [USACO5.5]矩形周长Picture[扫描线]

    题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...

  10. Django REST framework 使用简记

    最近在参与的项目中需要使用到dajngo REST framework工具包进行开发,之前参与的项目几乎都是清一色的使用原生的django(话说偶尔也会使用一下Flask,真心不怎么喜欢这个框架),之 ...