题目:

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

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

遍历,用个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. [转]HTTP中cache-control的应用及说明

    网页的缓存是由http消息头中的“Cache-control”来控制的,常见的取值有private.no-cache.max-age.must-revalidate等,默认为private.其作用根据 ...

  2. YARN指令

    如果是使用了Cloudera来安装到此路径下: /opt/cloudera/parcels/CDH-5.10.2-1.cdh5.10.2.p0.5/bin 执行: sudo ./yarn applic ...

  3. POJ1442:Black Box

    浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=1442 用对顶堆维护第\(k\)小 ...

  4. 2.2synchronized同步语句块

    使用synchronized虽然能够避免不同步的现象出现,但是也会出现弊端,比如代码执行时间过长,那么其他线程就必须等待该线程执行完毕释放锁之后才能拿到锁. 面对这种问题可以使用同步代码块来解决. 2 ...

  5. oracle--分页过程demo1

    oracle分页过程demo1: --ROWNUM用法 select o.*,rownum rn from (select * from emp) o where rownum<=10; sel ...

  6. PhpStorm选中相同文字高亮

    1.Setting(设置)->plugins->Browse Repositories 输入BrowseWordAtCaret 搜索,安装,然后重启: 2.Setting(设置) -> ...

  7. linux->windows主动推送文件同步目录数据 linux-windows数据目录同步

    1 .windows下安装openssh for windows工具,下载地址 https://www.mls-software.com/opensshd.html 2.修改openssh安装目录下e ...

  8. web实现本地缓存的方法

    Cookie(或者Cookies) 指一般网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). cookie一般通过http请求中在头部一起发送到服务器端.一条c ...

  9. ubunt14.04搭建lNMP

    一.安装mysql 1.  sudo apt-get update 2.  sudo apt-get install apt-get nginx 二.安装mysql 1.  sudo apt-get ...

  10. 09_android项目的目录结构

    R.java是由IDE自动生成的,不允许修改. Android Dependences  安卓的支持库 项目创建之后一般都会把安卓支持库的V4包导入进来. 项目打包的时候assets的内容并不会被编译 ...