1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次

本文介绍了一种高效查找数组中重复数字的方法,通过遍历数组并利用数组元素与下标的关系来标记已访问过的数字,最终找出所有重复出现的数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现
一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空
间,能否设计一个算法实现?
1001个元素相加减去1,2,3,……1000数列的和,得到的差即为重复的元素。
  int   Find(int   *   a)  
  {  
  int   i;//
变量  
  for   (i   =   0   ;i<=1000;i++)  
  {  
  a[1000]   +=   a[i];  
  }  
  a[1000]   -=   (i*(i-1))/2       //i
的值为1001  
  return   a[1000];  
  }
利用下标与单元中所存储的内容之间的特殊关系,进行遍历访问单元,一旦访问过的单
元赋予一个标记,利用标记作为发现重复数字的关键。代码如下:
void FindRepeat(int array[], int length)
{
    int index=array[length-1]-1;
    while ( true )
    {
       if ( array[index]<0 )
           break;
       array[index]*=-1;
       index=array[index]*(-1)-1;
    }
 
    cout<<"The repeat number is "<<index+1<<endl;
}
此种方法不非常的不错,而且它具有可扩展性。在坛子上有人提出:
对于一个既定的自然数 N ,有一个 N + M 个元素的数组,其中存放了小于等于 N 的所有
自然数,求重复出现的自然数序列{X}
 
对于这个扩展需要,自己在A_B_C_ABC(黄瓜儿才起蒂蒂)的算法的基础上得到了自己的算法
代码:
按照A_B_C_ABC(黄瓜儿才起蒂蒂)的算法,易经标记过的单元在后面一定不会再访问到,除非它是重复的数字,也就是说只要每次将重复数字中的一个改为靠近N+M的自然数,让遍历能访问到数组后面的单元,就能将整个数组遍历完。
代码:
*/
void FindRepeat(int array[], int length, int num)
{
 int index=array[length-1]-1;
 cout<<"The repeat number is ";
 while ( true )
 {
 if ( array[index]<0 )
 {
   num--;
   array[index]=length-num;
   cout<<index+1<<'t';
 }
 
 if ( num==0 )
 {
   cout<<endl;
  return;
 }
 array[index]*=-1;
 index=array[index]*(-1)-1;
 }
}
 
题目描述 给定一个含有n个数字的数组 a。 定义: 其中 & 运算表示为按位与。注意 l ≤ r l≤r。 对于以上描述,小可给出了q次查询。每次查询给出两个数字 l 和 k ,小可希望找出最大的 r ( l ≤ r ≤ n ) (l≤r≤n) ,使得 f ( l , r ) ≥ k f(l,r)≥k 输入描述 第一行:输入一个整数 t ,表示多组输入的样例组数。 对于每组测试数据: 第一行:输入一个正整数 n,表示数组长度。 第二行:输入 n 个正整数,表示数组a。 第三行:输入一个正整数 q,表示查询次数。 接下来q行:每行输入两个正整数 l 和 k ,表述如题 输出描述 对于每次查询,输出对应的答案,如果不存在这样的r,输出-1 。 输出格式为:同一组数据的答案在同一行,以空格为间隔;不同组数据以换行间隔。 输入样例 3 5 15 14 17 42 34 3 1 7 2 15 4 5 5 7 5 3 1 7 4 1 7 5 7 2 3 2 2 7 19 20 15 12 21 7 11 4 1 15 4 4 7 12 5 7 输出样例 2 -1 5 1 5 2 2 2 6 -1 5 数据描述 25%的数据下: t = 1 , 1 ≤ n ≤ 1 0 0 , q ≤ 1 0 0 0 t=1,1≤n≤100,q≤1000 100%的数据下: 1 ≤ t ≤ 1 0 4 , 1 ≤ n ≤ 2 × 1 0 5 , 1 ≤ a i ≤ 1 0 9 1≤t≤10 ​4 ​​ ,1≤n≤2×10 ​5 ​​ ,1≤a ​i ​​ ≤10 ​9 ​​ 1 ≤ q ≤ 1 0 5 , 1 ≤ l ≤ n , 1 ≤ k ≤ 1 0 9 1≤q≤10 ​5 ​​ ,1≤l≤n,1≤k≤10 ​9 ​​ 数据保证多组输入的 n 的和不超过 2 × 1 0 5 2×10 ​5 ​​ ,同时 q 的和不超过 2 × 1 0 5 2×10 ​5 ​​ 。 c++代码
最新发布
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值