数组中重复的数字

题目:找出数组中重复的数字
在一个长度为 n 的数组里的所有数字都在 0~n-1 的范围内。
数组中某些数字是重复的,但是不知道有几个数字重复,也不知道每个数字重复了几次。
请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组 {2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。

方法一:利用哈希表

  • 思路:创建一个与给定数组str相同长度的新数组tmp,并对其进行零初始化。从头到尾遍历str,将str中对应的值作为tmp的下标,每转换一次则tmp中对应下标的值加1。遍历完成后,tmp中数值大于1的数组下标则为数组中重复的数字。

  • 时间复杂度为:O(n),空间复杂度为O(n)

  • 代码如下:

bool ReNumber(const char* str,int n)
{
	if (nullptr == str || n < 0) return false;
	for (int i = 0; i < n; i++)
	{
		if (str[i]<0 || str[i]> n - 1)
			return false;
	}
	char* tmp = new char[n]();//建立一个与str长度相同的数组
	bool flag = 0;
	int j = 0;
	for (int i = 0; i < n; i++)
	{
		j = str[i];
		tmp[j]++;
	}
	for (int j = 0; j < n; j++)
	{
		if (tmp[j] > 1)
			cout << j << " ";
		return true;
	}
	return false;
	cout << endl;
}

方法二:利用排序算法

  • 思路:先用快排排序将数组按从小到大的顺序排列,比较数组中当前数字与后面一个数字是否相同,并找到连续重复数字中的最后一个数字,若相同则输出重复数字,否则继续遍历排序后数组。
  • 时间复杂度为O(nlogn),空间复杂度为O(1)
  • 代码如下:
int partition(int* arr, int start, int end)
{
	int key = arr[start];
	while (start < end)
	{
		while (arr[end] >= key && start < end)
			end--;
		arr[start] = arr[end];
		while (arr[start] < key && start < end)
			start++;
		arr[end] = arr[start];
	}
	arr[start] = key;
	return start;
}
void QuickSort(int* arr, int start, int end)
{
	int k;
	if (start < end)
	{
		k = partition(arr, start, end);
		QuickSort(arr, start, k);
		QuickSort(arr, k + 1, end);
	}
}
void FindNum(int* arr, int length)
{
	if (nullptr == arr || length <= 0)
		return;
	for (int i = 0; i < length; i++)
	{
		if (arr[i]<0 || arr[i]> length - 1)
			return;
	}
	QuickSort(arr, 0, length - 1);//排序
	int i = 1;
	int j = 0;
	for (int i = 1; i < length; i++)
	{
		for ( j = i; j < length; j++)//找到连续重复数字的最后一个位置
		{
			if (arr[j] != arr[j + 1])
				break;
		}
		i = j;
		if (arr[i] == arr[i - 1])//判断是否重复
			printf("%d ",arr[i]);
	}
	printf("\n");
}

方法三

  • 思路:遍历数组,当扫描到下标为 i 时,设当前数字为 j ,则比较 j 与 i 是否相等,若相等继续遍历,否则将 j 与下标为 j 的数字比较,若相等则输出(即为重复数字),否则交换位置,继续重复此过程。
  • 时间复杂度为O(n),空间复杂度为O(1)
  • 代码如下:
void Swap(int& arr, int& brr)
{
	int tmp = arr;
	arr = brr;
	brr = tmp;
}
void FindNum(int* arr, int length)
{
	if (arr == nullptr || length <= 0)
		return;
	for (int i = 0; i < length; i++)
	{
		if (arr[i]<0 || arr[i]>length - 1)
			return;
	}
	for (int i = 0; i < length; i++)
	{
		while (arr[i] != i)
		{
			if (arr[i] == arr[arr[i]])
			{
				printf("%d ", arr[i]);
				break;
			}
			Swap(arr[i], arr[arr[i]]);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值