数组中只出现一次的数字升级版

/*
题目出处:《剑指offer——名企面试官精讲典型题目》P211
题目:一个整型数组除了两个数字之外,其它的数字都出现了两次。请写程序找出这两个只出现一个的数字。要求时间复杂度是O(n),空间复杂度是O(1);
*/
/*
解题思路,这题是数组中除了一个数字外,其它的数字都出现两次的题目的变形,所以我们也应该从这个地方入手。如果只有一个数字,我们只需要用零去异或数组的所有数字,最后的结果就是那个落单的数字。
那么这题的,最后异或所得的结果是 两个落单的数字异或的结果,首先,这个结果肯定不会是0,不然它们就相等,不符合题目要求。既然不是零,我们从这个数字中找到它的二进制数中的随便一位不是零的位数,
那么就可以把这两个落单数字区分开了,就相当于是把这个数组分成的某个二进制位是否为1的两个数组。接着我们就可以按照一个数组所有数字都出现两次,只有一个数字出现一次的方法来做了。下面的解法是取异或结果的二进制数最右边的1的位置。
*/


#include<iostream>
using namespace std;

class TwoNumbersAppearOnce
{
public :
	TwoNumbersAppearOnce (){};
	~TwoNumbersAppearOnce(){};

	void FindNumsAppearOnce(int data[], int length, int *numOne, int *numTwo)
	{
		if(data == NULL || length<2)
			return ;

		int i;
		int result = 0;
		for(i=0; i<length; ++i)
			result = result ^ data[i];
		
		int indexOf1 = FindFirstRightOf1(result);
		*numOne = 0;
		*numTwo = 0;
		for(i=0; i<length; ++i)
		{
			if(isOne(data[i],indexOf1))
				*numOne = *numOne ^ data[i];
			else
				*numTwo = *numTwo ^ data[i];
		}

	}

private:
	int FindFirstRightOf1(int result)
	{
		int index = 0;
		while((result & 0x1)==0 && index<sizeof(int)*8)
		{
			++index;
			result = result>>1;
		}
		return index;
	}

	bool isOne(int numOne , int index)
	{
		numOne = numOne >>index;
		if((numOne & 0x1))
			return true;
		return false;
	}
};


int main()
{
	TwoNumbersAppearOnce twoNumbersAppearOnce;
	int arr[8] = {2,2,1,3,4,4,5,5};
	int numOne;
	int numTwo;
	
	twoNumbersAppearOnce.FindNumsAppearOnce(arr,8, &numOne, &numTwo);
	cout<<numOne<<" "<<numTwo<<endl;

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值