题目:

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

看题目脑子里就出现做法了:

遍历,用个HashMap来记录出现的次数,然后再遍历HashMap返回的EntrySet找出出现一次的数字搞定。

代码顺便上下吧:

public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
Integer count;
for(int temp : array) {
if( (count = map.get(temp)) == null )map.put(temp, 1);
else map.put(temp, ++count);
}
num1[0] = -1;num2[0] = -1;
Set<Entry<Integer, Integer>> entrySet = map.entrySet();
for(Entry<Integer, Integer> temp : entrySet) {
if( (count = temp.getValue()) == 1 && num1[0] == -1)num1[0] = temp.getKey();
else if(count == 1)num2[0] = temp.getKey();
}
}

然后看牛客网的讨论,原来可以用异或操作很帅气地解决这个问题哈哈,来记录一下。

基础知识:

1. 0和任何数字异或都为它自己,这个也很容易理解,拿个数字试试就知道辽。
2. 结合律:a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;
3. a ⊕ b ⊕ a = b.
当然还有其他运算规律,可以去百度百科看哈哈:

思路:(来自牛客的一个小伙子)

链接:https://www.nowcoder.com/questionTerminal/e02fdb54d7524710a7d664d082bb7811
来源:牛客网

只有一个数出现一次时,我们把数组中所有的数,依次异或运算,最后剩下的就是落单的数,因为成对儿出现的都抵消了。
 
依照这个思路,我们来看两个数(我们假设是AB)出现一次的数组。我们首先还是先异或,剩下的数字肯定是A、B异或的结果这个结果的二进制中的1,表现的是A和B的不同的位
 
我们就取第一个1所在的位数,假设是第3位,接着把原数组分成两组,分组标准是第3位是否为1。如此,相同的数肯定在一个组,因为相同数字所有位都相同,而不同的数,肯定不在一组。然后把这两个组按照最开始的思路,依次异或,剩余的两个结果就是这两个只出现一次的数字。

然后上一下我自己根据这个思路写的代码,已经通过:

/*高端的位运算法*/
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int firstXorResult = 0;//0和任何数异或都为本身
for(int temp : array) {
firstXorResult ^= temp;//异或满足结合率,a^b^a = b
}
//这样得到的firstXorResult就是唯一两个只出现一次的数字的亦或结果,也就是这个firstXorResult中为1的地方,就是这两个数字在位上面不同的地方
int shiftBit = 0;
while(shiftBit <= 31) {//这个循环是看从最低位开始,哪个位是第一个不同的,也就是为1的
if( (firstXorResult & (1 << shiftBit)) != 0 )break;
shiftBit++;
}
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>(); for(int temp : array) {
//根据刚刚的shiftBit,把数字分成两份,一份相与为0,一份不为0。首先肯定那两个只出现一次的数字肯定分开的;然后相同的数字肯定分到一个list
if( (temp & (1 << shiftBit)) == 0 ) {
list1.add(temp);
} else {
list2.add(temp);
}
} int result1 = 0, result2 = 0;
for(int temp : list1) {//异或结束得到的就是结果
result1 ^= temp;
}
for(int temp : list2) {
result2 ^= temp;
}
num1[0] = result1;
num2[0] = result2;
}

剑指Offer——数组中只出现一次的数字(一个很帅的异或解法)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. BZOJ2428:[HAOI2006]均分数据

    我对模拟退火的理解:https://www.cnblogs.com/AKMer/p/9580982.html 题目传送门:https://www.lydsy.com/JudgeOnline/probl ...

  2. Poj 2403 Hay Points(Map)

    一.题目大意 实现一个工资计算系统.工资的计算规则是:首先,给定一些关键字和对应的价值,这个相对于字典.然后给出的是求职者的描述,如果这个描述中包含关键字则加上对应的价值,总得价值就是这个求职者的工资 ...

  3. MySQL on Azure高可用性设计 DRBD - Corosync - Pacemaker - CRM (二)

    在上一篇文章中描述了MySQL HA on Azured 设计思路,本篇文章中将描述具体的部署,每个组件的安装和配置. 整体的设计架构如下: 下面将是所有组件的安装配置过程,所有的虚拟机是CentOS ...

  4. C#中DataTable用法

    一.select方法1.筛选出男性且名字中带有李的人然后按照生日降序排列(1)DataRow[] rows=DataTable.Select("sex='"+"男&quo ...

  5. ubantu在登录界面一致循环的问题

    1.进入非图形化界面:在登录界面同时按下ctrl+alt+f1(有的需要同时按下ctrl+alt+f1+fn) 2.:输入你的账户名回车     *注意;这里是帐户名,而不是密码 3.:输入你的密码回 ...

  6. 杂项-权限管理:Ralasafe

    ylbtech-杂项-权限管理:Ralasafe Ralasafe 是用Java编写的开源(MIT协议)访问控制中间件.它能够轻松处理登录控制.URL权限控制和(业务级)数据级权限管理,实现权限与业务 ...

  7. js点滴知识(1) -- 获取DOM对象和编码

    在今天的工作中发现了一些小的问题,在网上查了一下,才知道自己的js才是冰山一角,以后要虚心向他人学习,要虚怀若谷. 发现一:js获取DOM对象与jquery的区别 先前总以为,二者是一样的,最近才知道 ...

  8. jquery获取设置服务器控件的方法

    jquery获取设置服务器控件的方法 获取TextBox,HiddenField,Label的值.例如: <asp:TextBox ID="txtBoxID" runat=& ...

  9. 安装 ambaria

    hadoop安装 wget http://public-repo-1.hortonworks.com/ambari/centos6/1.x/updates/1.2.4.9/ambari.repo cp ...

  10. Centos 7安装与配置chef

    背景:随着DevOps 逐渐流行起来,越来越多的工作需要自动化处理,而chef就是其中一款能实现自动化管理的工具,掌握类似chef这样的自动化工具,相信会使你在未来的竞争中更具优势. 俗话说“好记性不 ...