您的位置:首页 > 其它

题目3:数组中重复的数字

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

代码如下:void duplicate(int a[],int m)
{
if(a!=NULL&&m>0)
{
for(int i=0;i<m;++i)
{
for(int j=i+1;j<m;j++)
{
if(a[i]==a[j]){
cout<<a[i]<<endl;
break;
}
}
}
}
}
上述代码是我自己写的,并没有按照教材根据下标与数字的对应关系去做交换,在时间复杂度上和空间复杂度上要比它的高,但是这样做比较简洁。
下面贴出教材上的代码,在原数组上交换:bool duplicate(int numbers[], int length, int* duplication)
{
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]])
{
*duplication = numbers[i];
return true;
}

// 交换numbers[i]和numbers[numbers[i]]
int temp = numbers[i];
numbers[i] = numbers[temp];
numbers[temp] = temp;
}
}

return false;
}     二 不修改数组找出重复的数字
    在一个长度为为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为9的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。

    我们以长度为8的数组{2,3,5,4,3,2,6,7}为例分析查找的过程。根据题目要求,这个长度为8的所有数字都在1~7的范围内。中间的数字4把1~7的范围分为两段,一段是1~4,另一段是5~7。接下来我们统计1~4这4个数字在数组中出现的次数,它们一共出现了5次,因此这4个数字中一定有重复的。

    接下来我们再把1~4的范围一分为二,一段是1、2两个数字,另一段是3、4两个数字。数字1或者2在数组中一共出现了两次。我们再统计数字3或者4在数组中出现的次数,它们一共出现三次。这就意味着3、4两个数字中一定有一个重复了。我们再分别统计这两个数字在数组中出现的次数。接着我们发现数字3出现了两次,以一个重复的数字。

    上述思路可以用如下代码实现:
int getDuplication(const int* numbers, int length)
{
if(numbers == nullptr || length <= 0)
return -1;

int start = 1;
int end = length - 1;
while(end >= start)
{
int middle = ((end - start) >> 1) + start;
int c
4000
ount = countRange(numbers, length, start, middle);
if(end == start)
{
if(count > 1)
return start;
else
break;
}

if(count > (middle - start + 1))
end = middle;
else
start = middle + 1;
}
return -1;
}

int countRange(const int* numbers, int length, int start, int end)
{
if(numbers == nullptr)
return 0;

int count = 0;
for(int i = 0; i < length; i++)
if(numbers[i] >= start && numbers[i] <= end)
++count;
return count;
}上述代码按照二分查找的思路,如果输入长度为n的数组,那么函数countRange将被调用O(logn)次,每次需要O(n)的时间,因此总的时间复杂度是O(nlogn),空间复杂度O(1)。但是这个算法并不能找到所有重复的数字。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐