【3】数组中只出现一次的数字

简介: 题目:输入一个整型数组,数组里除了两个数出现一次之外,其它所有数字出现的次数都是2次,求这两个数字。要求时间复杂度为O(n),空间复杂度为O(1) 1 题目要求时间复杂度为O(n)并且空间复杂度为O(1)。

题目:输入一个整型数组,数组里除了两个数出现一次之外,其它所有数字出现的次数都是2次,求这两个数字。要求时间复杂度为O(n),空间复杂度为O(1)


1 题目要求时间复杂度为O(n)并且空间复杂度为O(1)。这个时候朴素的方法利用数字来记录出现次数的方案都是不行的。

2 根据题目的特点,只有两个数出现一次,其它的所有数据都是出现2次。如果这两个数是a和b,那么对这个数组异或的结果就是a^b。现在我们就是要考虑怎么把数组分成两部分,一部分含有a,一部分含有b,则每部分异或的结果即为两个数a和b的值

3 因为a肯定不等于b,所以a^b的结果肯定不会等于0,那么我们可以就去这个异或结果中最右边的第一个1的位置,根据这个位置来划分这个数组,这个位置是1的位一部分,不是1的分为一部分。

4 例如数组{2,4,3,6,3,2,5,5},数组异或的结果为2,二进制位0010最右边1的位置为第二位。则我们把数组分成两部分{2,3,6,3,2}中每个数的二进制最右边第二位为1,剩下一部分{4,5,5}中每个数二进制最右边第二位为0。

5 求出两部分之后我们就可以直接对每部分求异或即可求出两个数的值


//找到两个只出现一次的数
void FindNumAppearOnce(int *arrNum, int n){
	//空指针和个数小于2都是不合法的数据
	if(arrNum == NULL || n < 2){
	    return;
	}
	//先求出总的异或的值
	int sum = 0;
	for(int i = 0; i < n; i++){
	    sum ^= arrNum[i];
	}
	//找到sum的右边第一个1的位置
	int pos = 0;
	while((sum & 1) != 1 && (pos <= 32)){
	    pos++;
		sum >>= 1;
	}
	//没有找出第一个1的位置
	if((pos == 0) || (pos > 32)){
	    return;
	}
	//定义两个数为
	int numOne = 0;
	int numTwo = 0;
	//枚举求出
	int num = 1<<pos;
	cout<<num<<endl;
	for(int i = 0; i < n; i++){
		if((arrNum[i]&num) != 0){
		    numOne ^= arrNum[i];
		}
		else{
		    numTwo ^= arrNum[i];
		}
	}
	cout<<numOne<<" "<<numTwo<<endl;
}


目录
相关文章
|
6天前
数一下 1到 100 的所有整数中出现多少个数字9并输出这些数字
数一下 1到 100 的所有整数中出现多少个数字9并输出这些数字
19 0
|
3天前
28.求任意一个整数的十位上的数字
28.求任意一个整数的十位上的数字
13 3
|
6天前
|
索引
Leetcode 给定一个数组,给定一个数字。返回数组中可以相加得到指定数字的两个索引
Leetcode 给定一个数组,给定一个数字。返回数组中可以相加得到指定数字的两个索引
|
10月前
数组中插入一个数字
数组中插入一个数字
46 0
|
10月前
删除数组中指定的数字
删除数组中指定的数字
67 0
|
12月前
7-10 求数字个数
7-10 求数字个数
42 0
|
JavaScript 前端开发
数字和字符串相加
数字和字符串相加
97 0
|
算法
如何在不把数字转为字符串的前提下反转数字
算法问题:如何在不把数字转为字符串的前提下反转数字
53 0
|
存储 算法 Python
python 力扣算法实现2 :#给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 # #最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
python 力扣算法实现2 :#给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 # #最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
|
开发框架 .NET C#
C# 找出数组中只出现了一次的数字
.NET 生态越来越好,初学的朋友也越来越多。处理同一件简单的问题,随着我们知识的积累解决问题的方法也会越来越多。 开始学习一门新的语言,我们经常会去解决之前用别的语言解决过无数次的老问题,今天我们来看看这么一道简单的查重题。
108 0