找出数组中重复的数字!!
长度为n的数组,所有数字都在0~n-1的范围内,某些数字可能会重复,找出任意一个重复数字,如 [2, 3, 1, 4, 2, 1],输出 2 或 1
思路1:
对数组进行排序,在遍历数组;时间复杂度过大(nlogn)
思路2:
利用哈希表,哈希表初始化为0;从头到尾扫描原数组,在与元素相等的下标位+1;若与当前数组元素相等的哈希表下标处元素 = 1;则说明该元素重复,改思路时间复杂度O(n),空间复杂度O(n)
思路3:
因为数组元素都在0~n-1的范围内,所以当数组排序之后,如果没有重复数字,则数字 i 会出现在下标 i 处,否则就有重复数字;
利用该特征,从头到尾扫描数组
①当扫描的下标 i 等于该处的元素 m 时,继续扫描;
②当 i != m 时,则用arr[i] 和 arr[m] 处的元素比较,若arr[i] == arr[m],有重复数字,返回;否则,将 arr[i] 和 arr[m] 进行交换,让数字 m 位于下标 m 处;
③用同样的规则遍历数组,若有重复数字,返回该数字;若遍历完了数组,则说明无重复数字
程序代码
bool Duplicate(int *arr, int len, int *val)
{
if(arr == NULL || len <= 0)
return false;
for(int i = 0;i < len; i++)
{
if(arr[i] == i) //arr[i]在自己相应的元素位上
continue;
while(arr[i] != i)
{
if(arr[arr[i]] == arr[i]) //有重复数字
{
*val = arr[i];
return true;
}
else //交换 arr[i] 和 arr[arr[i]],使arr[i] 在自己对应的元素位上
{
int tmp = arr[i];
arr[i] = arr[tmp];
arr[tmp] = tmp;
}
}
}
return false;
}
int main()
{
int arr[10] = {1,2,3,2,5,6,7,8,9,1};
int num; //接受重复数字
if(Duplicate(arr, 10, &num))
{
printf("有重复数字:%d\n", num);
}
else
{
printf("无重复数字\n");
}
return 0;
}