剑指offer-56

数组中数字出现的个数

56.1数组中只出现一次的两个数字,一个整形数组里除了两个数字外,其余都出现了两次,找出这两个数字,要求时间复杂度O(N),空间复杂度o(1)

解法一:hash散列表存储每个出现数字的次数,遍历整个数组,时间满足,空间不满足

解法二:依次遍历所有数字,查看余下数字有没有重复,时间不满足

解法三:利用异或法则,两对两对出现,有一对数字不同,所有数字依次异或后,成对的被消去,剩下单次数字a和b异或的结果c,c可以去还愿a或者b,一次只能一个,再将该数与原数组与运算后,结果大于1的为A组,结果等于0的为B组,A组B组内部再各进行一次异或运算,结果即是

[2 4 3 6 3 2 5 5]=> 2^4^ 3^ 6^ 3^ 2^ 5^ 5=4^6=2  => 2^4=6, 6^2=4, 2对应二进制内为1的位数可将4、6区分,用2与原数组各数字进行与运算后筛得[2 3 6 3 2]、[4 5 5]两组数字,两数组内部再各自内部与一次,2^3 ^6^ 3^ 2=6, 4^5^5=4

void FindNumsAppearOnce(int data[], int length, int* num1, int* num2)//diy
{
	if (data == nullptr || length < 2) return;
	int resultXOR = 0;
	for (int i = 0; i < length; i++)
		resultXOR ^= data[i];

	*num1 = 0;
	*num2 = 0;
	for (int i = 0; i < length;i++)
	{
		if ((data[i] & resultXOR)>0)
			(*num1) ^= data[i];
		else if ((data[i] & resultXOR) == 0)
			(*num2) ^= data[i];
	}
	return;
}

56.2 数组中唯一只出现一次的数字,在数组中除一个数字只出现一次外,其它都出现了三次,请问是哪一个数字

解法一:空间换时间,hashmap存储出现数字和次数

解法二:int型32位,记录二进制每一位1的个数,最后每一位对3取余,转换成整数即只出现一次的数字

int FindNumberAppearingOnce(int numbers[], int length)//diy
{
	if (numbers == nullptr || length <= 0) throw new std::exception("Invalid input.");

	int tempArr[32] = { 0 };
	for (int i = 0; i < length;i++)
	{
		int tempNum = numbers[i];
		for (int j = 31; j >= 0;j--)
		{
			if ((tempNum & 1) == 1)
				tempArr[j]++;
			tempNum=tempNum >> 1;
		}
	}

	int ret = 0;
	for (int i = 0; i <= 31;i++)
	{
		ret=ret << 1;
		if (tempArr[i] % 3)
			ret++;
	}
	return ret;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值