《剑指Offer——数组中只出现一次的两个数字,数组中唯一只出现一次的数字》代码

Posted 穿迷彩服的鲨鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer——数组中只出现一次的两个数字,数组中唯一只出现一次的数字》代码相关的知识,希望对你有一定的参考价值。


前言

//============================================================================
// 《剑指Offer——数组中只出现一次的两个数字,数组中唯一只出现一次的数字》代码
//============================================================================
// 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序
// 找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
//============================================================================
// 题目:在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。请
// 找出那个吃出现一次的数字。
//============================================================================


一、示例

1.数组中只出现一次的两个数字,

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

示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]

示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
=======================================================*/

2.数组中唯一只出现一次的数字

/*=====================================================
在一个数组 nums 中除一个数字只出现一次之外,
其他数字都出现了三次。请找出那个只出现一次的数字。

示例 1:
输入:nums = [3,4,3,3]
输出:4

示例 2:
输入:nums = [9,1,7,9,7,9,7]
输出:1
======================================================*/

二、代码解析

1.新建.cpp文件

代码如下(示例):

//============================================================================
// 《剑指Offer——数组中只出现一次的两个数字,数组中唯一只出现一次的数字》代码
//============================================================================
// 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序
// 找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
//============================================================================
// 题目:在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。请
// 找出那个吃出现一次的数字。
//============================================================================



#include <iostream>
#include<vector>
#include<unordered_map>
using namespace std;

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

示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]

示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
=======================================================*/
/*法一-----哈希表*/
vector<int> singleNumbers(vector<int>& nums)
{
	vector<int> result;
	unordered_map<int, int> map;
	for (int num : nums)
	{
		map[num]++;
	}
	for (auto item : map)
	{
		if (item.second == 1)
		{
			result.push_back(item.first);
		}
	}
	return result;
}
/*法二-----异或运算*/

// 找到num从右边数起第一个是1的位
unsigned int FindFirstBitIs1(int num)
{
	int indexBit = 0;
	while (((num & 1) == 0) && (indexBit < 8 * sizeof(int)))
	{
		num = num >> 1;
		++indexBit;
	}

	return indexBit;
}

// 判断数字num的第indexBit位是不是1
bool IsBit1(int num, unsigned int indexBit)
{
	num = num >> indexBit;
	return (num & 1);
}

void FindNumsAppearOnce(int data[], int length, int* num1, int* num2)
{
	if (data == nullptr || length < 2)
		return;

	int resultExclusiveOR = 0;
	for (int i = 0; i < length; ++i)
		resultExclusiveOR ^= data[i];

	unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);

	*num1 = *num2 = 0;
	for (int j = 0; j < length; ++j)
	{
		if (IsBit1(data[j], indexOf1))
			*num1 ^= data[j];
		else
			*num2 ^= data[j];
	}
}


/*=====================================================
在一个数组 nums 中除一个数字只出现一次之外,
其他数字都出现了三次。请找出那个只出现一次的数字。

示例 1:
输入:nums = [3,4,3,3]
输出:4

示例 2:
输入:nums = [9,1,7,9,7,9,7]
输出:1
======================================================*/
/*法一---嘻哈表*/
int singleNumber(vector<int>& nums)
{
	unordered_map<int, int> map;
	for (int num : nums)
	{
		map[num]++;
	}
	for (auto item : map)
	{
		if (item.second == 1)
		{
			return item.first;
		}
	}
	return 0;
}

/*法二--位运算*/
int FindNumberAppearingOnce(vector<int>& nums)
{
	if (nums.empty())
	{
		return 0;
	}
	int bitSum[32] = { 0 };
	for (int i = 0; i < nums.size(); ++i)
	{											//3,4,3,3
		long bitMask = 1;
		for (int j = 31; j >= 0; --j)
		{
			int bit = nums[i] & bitMask;		//bit=1 
			if (bit != 0)
			{
				bitSum[j] += 1;					//bitSum[31]=1,
			}
			bitMask = bitMask << 1;				//bitMask=2
		}
	}
	int result = 0;
	for (int i = 0; i < 32; ++i)
	{
		result <<= 1;
		result += bitSum[i] % 3;
	}
	return result;
}

int main()
{
	vector<int> nums = { 1,1,1,2,3,3,3 };
	vector<int> nums1 = { 1,1,2,5,3,3 };
	int data[] = { 1,1,2,5,3,3 };
	cout << "数组中只出现一次的两个数字" << endl;
	vector<int> result = singleNumbers(nums1);
	int value1, value2;
	FindNumsAppearOnce(data,6,&value1,&value2);
	cout << "法一--->嘻哈表--->" << result[0] << " " << result[1] << endl;
	cout << "法二--->异或运算--->" << value1 << " " << value2 << endl;
	cout << "数组中唯一只出现一次的数字" << endl;
	cout << "法一--->嘻哈表--->" << singleNumber(nums) << endl;
	cout << "法二--->位运算--->" << FindNumberAppearingOnce(nums) << endl;
	return 0;
}

三,测试


以上是关于《剑指Offer——数组中只出现一次的两个数字,数组中唯一只出现一次的数字》代码的主要内容,如果未能解决你的问题,请参考以下文章

《剑指offer》第五十六题I:数组中只出现一次的两个数字

剑指offer:数组中只出现一次的数字

剑指offer数组中只出现一次的数字

剑指offer-数组中只出现一次的数字

剑指offer数组中只出现一次的数字

剑指offer:数组中只出现一次的数字