LeetCode第12天--数组中数字出现的次数

本文介绍了一种利用异或运算解决编程问题的方法,快速找到整型数组中仅出现一次的两个数字。通过异或特性,将重复数字分开并找出不同组的数字,从而实现O(n)时间复杂度和O(1)空间复杂度的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组中数字出现的次数

问题描述

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

 示例

输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]

解题思路

用异或方法进行解决,我们都知道要是有一个数只出现一次,根据异或的原理,那么我们将所有数全部异或,则结果就为出现一次的数字。这个问题是有两个数出现了一次,那么首先的思路就是将这两个数分开,分成两组。使得

  • 两个只出现一次的数字在不同的组中;

  • 相同的数字会被分到相同的组中。

如何将两个数组分开呢?

首先我们先将所有数进行异或,这个异或结果即是两个不同的数异或的结果,然后找出其中任意一位1,然后进行分组。

  • 首先,两个相同的数字的对应位都是相同的,所以一个被分到了某一组,另一个必然被分到这一组。
  • 其次,因为取的数为两个数异或结果为1的那一位,代表在这个位上,两个数是不同的(分别为1、0或0、1),所以一个数被分到了某一组,另一个数一定会被分到其他的组。

分好组后,将每组的数字分别异或得到的结果就是只出现一次的那个数。

代码实现:

void singleNumbers(int* nums, int numsSize)
{
	int sum = 0;
	//先求出两个不同数的异或结果
	for (int i = 0; i < numsSize; i++)
	{
		sum ^= nums[i];
	}

	int x = 1; //找出异或结果中任意一位1
	while ((x & sum) == 0)
	{
		x <<= 1;
	}

	int* ret = (int*)malloc(sizeof(int) * 2);
	ret[0] = ret[1] = 0;  //进行分组,将不同的数分在不同的2组
	for (int j = 0; j < numsSize; j++)
	{
		if (x & nums[j])
		{
			ret[0] ^= nums[j];
		}
		else
		{
			ret[1] ^= nums[j];
		}
	}
	printf("%d,%d\n", ret[0], ret[1]);
}

结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值