剑指offer:数组中只出现一次的数字
题目描述:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路分析:
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:数组中只出现一次的数字的更多相关文章
- 剑指Offer 数组中只出现一次的数字
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 因为有2个数字只出现了一次,而其他的数字都是2次,可以通过异或运算,得到最后这2个只 ...
- 剑指Offer——数组中只出现一次的数字
题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 数组中一共有偶数个数.两个数字只出现过一次. 相同数异或在一起等于0,那么将所有数异或 ...
- 剑指Offer——数组中只出现一次的数字(一个很帅的异或解法)
题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 看题目脑子里就出现做法了: 遍历,用个HashMap来记录出现的次数,然后再遍历HashMap返回 ...
- 用java刷剑指offer(数组中只出现一次的数字)
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 牛客网链接 思路 链接:https://www.nowcoder.com/questionTer ...
- leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)
136. Single Number 除了一个数字,其他数字都出现了两遍. 用亦或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1 2.与自己亦或为0,与0亦或为原来的数 class Solu ...
- 剑指Offer-40.数组中只出现一次的数字(C++/Java)
题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 我们知道,两个相同的数字异或的结果等于0,所以利用这个性质将数组中所有的数字异或,求得的结 ...
- 剑指offer--35.数组中只出现一次的数字
时间限制:1秒 空间限制:32768K 热度指数:198150 本题知识点: 数组 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. class ...
- 剑指 Offer —— 数组中重复的数字
数组中的重复数字 题目描述 牛课网链接 长度为 n 的数组里,所有数字都在 0 到 n-1 的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一 ...
- 剑指offer 数组中重复的数
在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{ ...
- 剑指offer——数组中出现次数超过一半的数字(c++)
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如 ...
随机推荐
- vue辅助函数mapStates与mapGetters
状态管理器 <!-- store.js: --> import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export de ...
- JavaWeb 之 JSON
一.概述 1.概念 JSON:JavaScript Object Notation JavaScript对象表示法 2.基本格式 var p = {"name":"张三 ...
- 【RAC】 RAC For W2K8R2 安装--操作系统环境配置 (二)
[RAC] RAC For W2K8R2 安装--操作系统环境配置 (二) 一.1 BLOG文档结构图 一.2 前言部分 一.2.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可 ...
- StringUtils系列之StringUtils.isNotBlank()和StringUtils.isNotBlank()的区别
/** 1. * StringUtils.isNotBlank(); * 判断参数是否不为空. * 1.如果不为空返回true. * 2.如果为空返回false. * StringUtils.isNo ...
- 【转】高性能网络编程4--TCP连接的关闭
TCP连接的关闭有两个方法close和shutdown,这篇文章将尽量精简的说明它们分别做了些什么. 为方便阅读,我们可以带着以下5个问题来阅读本文: 1.当socket被多进程或者多线程共享时,关闭 ...
- 【原创】STM32低功耗模式及中断唤醒(基于BMI160及RTC)的研究
预研目标 六轴静止时,终端进入低功耗模式:六轴震动时,终端正常工作模式,从而极大减少非工作时的电流消耗. 解决方案 机器静止时,依据六轴算法,CPU进入休眠(停止)模式:机器工作时,触发六轴中断唤醒C ...
- Codeforces Round #560 (Div. 3) Microtransactions
Codeforces Round #560 (Div. 3) F2. Microtransactions (hard version) 题意: 现在有一个人他每天早上获得1块钱,现在有\(n\)种商品 ...
- Python中单引号、双引号、三引号的区别
在学习python中的sqlite时发现实例的语句创建表时是用的三个单引号,但其他的表操作语句都是双引号,就不明白,于是搜了一下,在此做一下笔记. import sqlite3 conn = sqli ...
- JQuery DOM操作(属性操作/样式操作/文档过滤)
jQuery——入门(三)JQuery DOM操作(属性操作/样式操作/文档过滤) 一.DOM属性操作 1.属性 (1).attr() 方法 语法:$(selector).attr(name|prop ...
- Git学习笔记--实践(三)
文中红色的文字(标为:## 插曲)是在Git学习/实践过程中,我个人遇到的一些问题,每个“## 插曲”之后,都有相应的解决方案. 一.创建版本库 版本库又名仓库,英文名repository,可简单的理 ...