【剑指Offer】40、数组中只出现一次的数字
题目描述:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
解题思路:
这道题目相对比较难,一般情况下,我们首先可以想到的是顺序扫描数组,但其时间复杂度为O(n^2)。进一步也可以想到用哈希表保存每一个数次出现的次数,但是这使用了辅助空间,空间复杂度为O(n)。显然均不满足题目要求。
我们先来看一个比较简单的情况,如果数组中只有一个数字出现一次,其他都出现两次。那么我们应该可以想到异或运算。异或运算有一个比较好的性质是:相同为0,相异为1。也就是说,任何一个数字异或它自己都等于0,而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。
编程实现(Java):
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
/*
思路:数组中的元素先依次异或,相同为0,则得到的是两个只出现一次的数的异或结果
对于得到的异或结果,找到其第一个为1的位
该位为1,说明两个只出现一次的数该位不同,所以按照该位是0还是1将数组分成两部分
这样,出现两次的数字都会分到同一个部分,而两个只出现一次的数正好被分开,再各自异或可得结果
*/
if(array==null||array.length<2)
return ;
int res=0;
for(int num:array) //数组中的元素先依次异或,相同为0,则得到的是两个只出现一次的数的异或结果
res ^= num;
int index=0; //找到其第一个为1的位
for(;index<32;index++){
if(((res>>index) & 1)==1)
break;
}
num1[0]=0;
num2[0]=0;
for(int num:array){ //按照该位是0还是1将数组分成两部分,分别异或
if(((num>>index)&1)==1)
num1[0] ^= num;
else
num2[0] ^= num;
}
}
}
【剑指Offer】40、数组中只出现一次的数字的更多相关文章
- 剑指Offer 40. 数组中只出现一次的数字 (数组)
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 题目地址 https://www.nowcoder.com/practice/e02fdb54 ...
- [剑指offer] 40. 数组中只出现一次的数字
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 思路: 解法一: 哈希表 class Solution { public: void Find ...
- 《剑指offer》数组中只出现一次的数字
本题来自<剑指offer> 数组中只出现一次的数字 题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 思路一:在<剑指of ...
- 【剑指Offer】数组中只出现一次的数字 解题报告(Python)
[剑指Offer]数组中只出现一次的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- 剑指offer:数组中只出现一次的数字
题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路分析: 1. 直接想法,每个数字遍历,统计出现次数,复杂度O(n^2),超时. 2. 借助 ...
- Go语言实现:【剑指offer】数组中只出现一次的数字
该题目来源于牛客网<剑指offer>专题. 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 正常能想到哈希表来处理,但此题考查的是异或的知识, ...
- [剑指Offer] 40.数组中只出现一次的数
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. [思路]此题考察的是异或运算的特点:即两个相同的数异或结果为0. 此题用了两次异或运算特点: ( ...
- 【剑指offer】数组中只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 思路1:使用HashMap存上所有的数字,数字作为Key,Value为对应的出现次数.这种做法可以 ...
- 《剑指offer》-数组中只出现一次的数字
/* 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 如果是只有一个数字出现一次,那么所有数字做异或就得到结果: 现在有两个数字x,y分别出现一次 ...
- 【Java】 剑指offer(56-1) 数组中只出现一次的两个数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程 ...
随机推荐
- 让我们加密吧Let's encrypt
前言 如今的互联网越来越不安全,我们每个人的信息以及隐私不断被暴露,地下黑产盛行,经常收到垃圾短信,经常被陌生人的电话骚扰.我们的个人信息是怎么泄漏的呢?各种爬虫无时无刻不在互联网爬取着信息,各种嗅探 ...
- HDU 4509
很简单的排序题而已. #include <iostream> #include <cstdio> #include <algorithm> #include < ...
- string 和 vector 初探
标准库类型 string string 表示可变长的字符序列.是C++标准库类型的一部分,拥有很多优秀的性能. 定义 string 对象时如未人为初始化编译器会默认初始化为空字符串. string 对 ...
- Android 外部存储权限分析
不知道你有么有发现.来自菜鸟的成长史:http://blog.csdn.net/zjbpku/article/details/25161131. KitKat之后的版本号不再支持用户对外置SDcard ...
- Verilog与SystemVerilog编程陷阱:怎样避免101个常犯的编码错误
这篇是计算机类的优质预售推荐>>>><Verilog与SystemVerilog编程陷阱:怎样避免101个常犯的编码错误> 编辑推荐 纠错式学习,从"陷阱 ...
- extjs_07_combobox&tree&chart
1.combobox <%@ page language="java" import="java.util.*" pageEncoding="U ...
- SIPp web frontend(2)
SIP VoIP 測试交流群: 323827101 欢迎大家转载.为保留作者成果,转载请注明出处.http://blog.csdn.net/netluoriver,有些文件在资源中也能够下载.假设你没 ...
- C++ Web 编程(菜鸟教程)
C++ Web 编程(菜鸟教程) C++ Web 编程 什么是 CGI? 公共网关接口(CGI),是一套标准,定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的. CGI 规范目前是由 NC ...
- C语言和C++的应用领域都在哪些?学C语言好,还是学习C++好?
从事嵌入式开发十几年,基本上围绕着这两种编程语言展开,都可以直接操作底层的编程语言,用的越熟练越是感觉工具属性越强.虽然两种编程语言分属于不同的编程思想,用的时间长了觉得差异也不是很大,现在就个人的从 ...
- 工作2-5年,身为iOS开发的我应该怎么选择进修方向?
前言: 跳槽,面试,进阶,加薪:这些字眼,相信每位程序员都不陌生! 但是方向的选择,却不知如何抉择!其实最好的方向,已经在各个企业面试需求中完美的体现出来了: 本文展示了2份面试需求,以及方向的总结, ...