题目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)。但是这个算法并不能找到所有重复的数字。。。。。。
在一个长度为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)。但是这个算法并不能找到所有重复的数字。。。。。。
相关文章推荐
- 计蒜客题目 排序后的数组删除重复数字
- 算法题目一:如果数组中数字重复最多的次数大于数组长度的一半,返回1,否则返回0
- 题目:删除排序数组中的重复数字
- 题目:删除排序数组中的重复数字 II
- 程序员面试题目总结--数组(三)【旋转数组的最小数字、旋转数组中查找指定数、两个排序数组所有元素中间值、数组中重复次数最多的数、数组中出现次数超过一半的数】
- 程序员面试题目总结--数组(二)【二分查找、找出给定数字出现次数、两个有序整型数组交集、找出数组中唯一的重复元素、判断数组中的数值是否连续相邻】
- 数组中重复的数字
- 数组中重复的数字
- 一道Amazon经典的题目,经常会考到,给一个target数字以及一个数组,求所有的加起来为这个数字的组合
- 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? (基础c++)
- LintCode:删除排序数组中的重复数字 II
- c++ 删除整形数组中重复的数字
- 剑指offer-数组中重复的数字
- 题目1370:数组中出现次数超过一半的数字
- 【python】题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
- 排序数组中重复最对的数字长度
- 数组中重复的数字
- 题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
- 题目1386:旋转数组的最小数字
- 101. 删除排序数组中的重复数字 II