题目:找出数组中重复的数字
在一个长度为 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]]);
}
}
}