数组中只出现一次的数字

https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193&tPage=2&rp=4&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

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

思路:

先把整个数组的数字异或得到只出现一次的数字异或的结果。因为这个结果是只出现一次的数字异或的结果,所以异或的结果肯定会有 一个1, 然后找到这个异或结果的第一个1出现的位置,比如第n位。

根据这个1出现的位置把原来的数组分组,第n位位1的分到一个数组,不为1的分到另一个数组,

这样只出现一次的数字就会分到不同的数组。由于题目说其他数字只是出现一次,所以而这两个数组里面只有一个元素是只出现一次,就是题目所求的数字

比如 1 1 3 6 3 6 5 7 

整个数字异或的结果是res = 5^7 = 0010 第一个1出现的位置(从右边的第零位数起)是第1个位置。

按照第1位(同上从右边的第零位数起)是否为1把数组分成两个数组,

得到{3, 6, 3, 6, 7}     {1,1,5 }

两个数组分别自己异或,左边的得到7,右边得到1,所以数组只出现一次的是5 和7

 


class Solution {
public:
	vector<int >sub1;
	vector<int >sub2;
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2)
	{
		int length = data.size();
		if(length == 0)
			return ;
		int ans = 0;
		for(int i = 0; i < length; i++)//求整个数组异或的结果
			ans ^= data[i];
		//cout<<ans<<endl;

		int pos = getFirst(ans);//获取ans的第一个1出现的位置
		//cout<<pos<<endl;
		for(int i = 0; i < length; i++)
		{
			if(check(data[i], pos))//data[i]在二进制中第pos位是1
				sub1.push_back (data[i]);//分到数组sub1
			else
				sub2.push_back (data[i]);//分到数组sub2
		}
		int res_num1 = 0, res_num2 = 0; 
		for(int i = 0; i < sub1.size(); i++)//获得结果
			res_num1 ^= sub1[i];
		for(int i = 0; i < sub2.size(); i++)
			res_num2 ^= sub2[i];
		*num1 = res_num1;
		*num2 = res_num2;
		return ;

    }
	int getFirst(int ans )//获取ans第一个1的位置
	{
		int pos = 0;
		while(ans)
		{
			if(ans & 1)
				break;
			else
			{
				pos++;
				ans>>=1;
			}
		}
		return pos;

	}
	bool check(int x, int pos)//检验x的第pos位置是否为1
	{
		x = x>>pos;
		if(x & 1)
			return true;
		else
			return false;
	}

};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值