Numbers that appear only once (four types in total)

foreword

  So far dragon has encountered four topics called "Numbers that Appear Only Once", and now I have decided to summarize these four topics. Assuming that the highest difficulty is five stars, I will evaluate the difficulty of these four questions below (in my opinion).

ps:如果博友们还遇到了其他《只出现一次的数字》的题目,欢迎在评论区进行分享。

1. Difficulty level: ⭐

   Given an array of integers nums numsn u m s , all elements appear twice except for a certain element that appears only once. Find the element that appears only once.

  When the XOR operation of two numbers is performed, if the values ​​of the two numbers corresponding to a certain binary bit are the same, the value of the binary bit of the value obtained by the XOR is 0; if the two numbers correspond to a certain binary bit The value of the bit is different, then the value of the binary bit of the value obtained by XOR is 1.

Pay attention to understanding:

  • XOR any number with 0 and get itself. (The binary sequence of 0 is all 0s, and each binary bit of a number is different from 0 or unchanged)
  • The XOR of two identical numbers results in a value of 0. (The binary sequence of two identical numbers is the same, and the XOR of each binary bit is 0)

  In addition, since XOR also satisfies the commutative law and the associative ratio, we can convert the array nums numsThe elements in n u m s are XORed in turn. At this time, the numbers that appear twice in the array become 0 after XORing, and the result obtained by XORing is the number that only appears once.

code show as below:

int singleNumber1(vector<int>& nums) {
    
    
	int ret = 0;
	//通过范围for遍历容器,逐个异或
	for (auto e : nums)
	{
    
    
		ret ^= e;
	}
	return ret; //返回异或后的结果
}

2. Difficulty level: ⭐⭐

  gives you an array of integers nums numsn u m s , each element occurs exactly three times, except for one that occurs only once. Please find and return the element that appears only once.

   i n t int The size of the int type variable is 4 bytes, which is 32 bits. Since the binary sequence of the same number is the same, when we traversenums numsWhen the numbers in the n u m s array count the number of 1 occurrences in each bit in turn, the following situations will occur:

  • The number of occurrences of 1 in a bit is 0, indicating that the array nums numsThis bit is 0 for all numbers in n u m s , so a digit that occurs only once is also 0.
  • The number of occurrences of 1 in a bit is divided by 3 to obtain a 0 value, indicating that the array nums numsThis bit is 0 for numbers that appear only once in n um s .
  • The number of occurrences of 1 in a bit is 3, and the non-zero value is obtained after the remainder, indicating that the array nums numsThe bit of the number that appears only once in n u m s is 1, and it can be concluded that the number of occurrences of the bit at this time is 1 after taking the remainder of 3, and the remaining 1 is caused by only appearing once numbers provided.

  So when we iterate over nums numsAfter the n u m s array counts the number of occurrences of 1 for each bit, the 32 values ​​can be calculated by 3 in turn, and the resulting 32 0/1 sequences are the binary sequences of numbers that only appear once. .

code show as below:

int singleNumber2(vector<int>& nums) {
    
    
	int ret = 0;
	for (int i = 0; i < 32; i++) //int类型有32个比特位
	{
    
    
		int total = 0;
		//遍历nums,统计nums中第i个比特位为1的元素个数
		for (auto e : nums)
		{
    
    
			total += ((e >> i) & 1);
		}
		//如果第i个比特位为1的元素个数不能被3整除
		//则说明只出现一次的数字的这一比特位为1
		if (total % 3 != 0)
		{
    
    
			ret |= (1 << i); //将ret的第i个比特位设置为1
		}
	}
	return ret; //返回只出现一次的数字
}

3. Difficulty level: ⭐⭐⭐⭐

  Given an array of integers nums numsn u m s , where exactly two elements appear only once and the rest appear twice. Find those two elements that appear only once. You can return answers in any order.

  array nums numsExcept for the numbers that appear once in n u m s , the rest are numbers that appear twice, but we cannot directly traverse the array elements for XOR operation, because at this timenums numsThere are two numbers that appear once in the n u m s array. If we directly XOR all the numbers, the final result is actually the result of the XOR of these two numbers that appear once.

  If we could convert the array nums numsThe numbers in n u m s are divided into two groups, and the two numbers that appear once are divided into these two groups respectively. At this time, it is equivalent to finding the numbers that appear once in the two groups, and the two numbers appear once. There is only one number that appears once in the group. At this time, we perform the intra-group XOR on the two groups respectively, and the final two numbers are the arraynums numsTwo numbers in n u m s that appear only once.
insert image description here
  The question now becomes, how to divide these two numbers that only occur once into two different groups. This is actually easy because we directly nums the arraynumsWhen the elements in n u m s are XORed, what is actually obtained is the result of the XOR of these two numbers that only appear once. We call this resultret retr e t . Since the binary sequences of these two numbers that occur only once are different, inret retThere must be at least one bit that is not 0 in the binary sequence of ret , and the value of this bit must be different for these two numbers that appear only once. So we can group according to this bit, put the arraynums numsIn n u m s , the numbers whose bit is 1 are divided into one group, and the numbers whose bit is 0 are divided into another group. At this time, the two numbers that appear only once must be divided into two different groups. in the group.

The steps to solve the problem are roughly as follows:

  1. iterate over the array nums numsn u m s , XOR all the elements in the array to get the XOR resultret retret
  2. find out ret retAny bit in r e t that is not 0.
  3. According to this non-zero bit, nums numsXOR the numbers grouped in the n u m s array.
  4. The two values ​​obtained by the final group XOR are the two numbers that appear only once.

code show as below:

vector<int> singleNumber3(vector<int>& nums) {
    
    
	//1、遍历数组nums,对数组中的所有元素进行异或
	int ret = 0;
	for (auto e : nums)
	{
    
    
		ret ^= e;
	}

	//2、找出ret当中任意一个不为0的比特位(这里从低位到高位进行查找)
	int index = 0;
	while (((ret >> index) & 1) == 0)
	{
    
    
		index++;
	}

	//3、将nums数组中第index个比特位为1和不为1的数字分组进行异或
	int a = 0, b = 0;
	for (auto e : nums)
	{
    
    
		if ((e >> index) & 1) //第index个比特位为1的数字
		{
    
    
			a ^= e;
		}
		else //第index个比特位不为1的数字
		{
    
    
			b ^= e;
		}
	}
	
	//4、将这两个只出现一次的数字放到容器v当中进行返回
	vector<int> v;
	v.push_back(a);
	v.push_back(b);
	return v;
}

4. Difficulty level: ⭐⭐⭐

  Given an array of integers nums numsn u m s and an integerkkk , except that an element occurs only once, every other element occurs exactlykkk times. Please find and return the element that appears only once.

  Except for the number that only appears once in the array, no matter how many other numbers appear, we can actually solve it by counting the number of times each bit appears 1, but now we will get 32 ​​bits The number of occurrences of each 1 is paired with kkk performs the remainder operation, and the resulting 32 0/1 sequences are the binary sequences of numbers that appear once.

code show as below:

int singleNumber4(vector<int>& nums, int k) {
    
    
	int ret = 0;
	for (int i = 0; i < 32; i++) //int类型有32个比特位
	{
    
    
		int total = 0;
		//遍历nums,统计nums中第i个比特位为1的元素个数
		for (auto e : nums)
		{
    
    
			total += ((e >> i) & 1);
		}
		//如果第i个比特位为1的元素个数不能被3整除
		//则说明只出现一次的数字的这一比特位为1
		if (total % k != 0)
		{
    
    
			ret |= (1 << i); //将ret的第i个比特位设置为1
		}
	}
	return ret; //返回只出现一次的数字
}

Guess you like

Origin blog.csdn.net/chenlong_cxy/article/details/124383630