数组中重复的数字

/*
在一个长度位n的数组里面所有的数字都在0到n-1的范围内。

数组中某些数字是重复的,但不知道有几个数字重复了,也不知道

每个数字重复了几次。找到数组中任意一个重复的数字。例如,如果

输入长度为7的数组{2,3,1,0,2,5,3},那么对应的重复数组就是2或者3.
*/

/*
解法1:利用一个哈希表,从头到尾扫描数组中的每一个数字,得出结果。
时间复杂度为O(n),但是最坏情况下要创建一个n-1个大小的哈希表为代价。
*/

#include<iostream>
#include<unordered_map>

using namespace std;

unordered_map<int,int> g_hash_map;

//判断在哈希表中是否有重复的元素
inline bool is_duplicate(const int& num)
{
	if (g_hash_map.find(num) == g_hash_map.end())
	{
		g_hash_map[num] = 1;
		return false;
	}

	return true;
}

int main()
{
	int nums[] = { 2,3,1,0,2,5,3 };   //要查询的数组
	//遍历数组
	for (auto ite = begin(nums); ite != end(nums); ite++)
	{
		if (is_duplicate(*ite))
		{
			cout << "duplicate num = " << *ite << endl;
			break;
		}
	}

	return 0;
}

/*
解法2:不用另外再申请空间,就能完成的解法。如果第i个位置存放i,
那么因为数组中有重复的数字,那么必然有的位置存在多个数字。
从头到尾依次扫描这个数组中的每一个数字,当扫描到下标为i的数字m时,比较这个数字m
是不是等于i。如果是,扫描下一个数字,如果不是,拿它与第m位置的数字进行比较,如果重复
找到结果,如果不重复,交换位置。接下来再重复这个比较、交换的过程,直到发现一个重复的数字。
*/

#include<iostream>

using namespace std;

bool duplicate(int numbers[], int length, int* duplicate)
{
	if (numbers == nullptr || length == 0)
	{
		return false;
	}

	for (int i = 0; i < length; ++i)
	{
		if (numbers[i] < 0 || numbers[i]>length - 1)
		{
			return false;
		}
	}

	for (int i = 0; i < length; i++)
	{
		while (numbers[i] != i)
		{
			if (numbers[i] == numbers[numbers[i]])
			{
				*duplicate = numbers[i];
				return true;
			}

			int tmp = numbers[i];
			numbers[i] = numbers[tmp];
			numbers[tmp] = tmp;
		}
	}

	return false;
}

int main()
{
	int nums[] = { 2,3,1,0,2,5,3 };   //要查询的数组

	int result = -1;
	
	duplicate(nums, sizeof(nums) / sizeof(nums[0]), &result);

	cout << "duplicate = " << result << endl;

	return 0;
}

  

posted on 2021-10-17 23:02  xcxfury001  阅读(42)  评论(0)    收藏  举报

导航