n+1个范围是0~n的数字,找出所有重复的数字,O(n)基础上不用额外空间

本文介绍了一种在不使用额外空间的情况下,通过数组自身来查找0到n范围内的重复数字的O(n)时间复杂度算法。算法巧妙地利用数组元素作为索引来标记已访问的元素,重复的数字会引发特定的负数标记,从而快速识别。

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

n+1个范围是0~n的数字,找出所有重复的数字,O(n)基础上不用额外空间。

算法思想:

使用数组的值对应数组的下标,出现多对一的则说明重复。

算法:

遍历数组,每次访问前判断数组是否访问过(访问过的会被置为负数);
如果没访问过,则以当前数组的值为数组下标,访问其值:
若为负数,则此元素被访问过,即数组下标在数组值中多次出现,重复;
若非负,则此元素没被访问过,将其标记为访问过(取负值,0取数组长度的负 值);
如果访问过(访问过的数为负数),则再取负为数组下标(如果是数组长度,表明是0),访问其值:
若为负数,则此元素被访问过,即数组下标在数组值中多次出现,重复;
若非负,则此元素没被访问过,将其标记为访问过(取负值,0取数组长度的负 值)。

算法如下:
public static void alg(int[] array){
for(int i=0;i<array.length;i++){
if(0>array[i]){
if(-array.length == array[i]){
if(0>array[0])
System.out.println(0);
}
else if(0>array[-array[i]]){
System.out.println(-array[i]);
}
else{
if(0 == array[-array[i]])
array[-array[i]] = -array.length;
else if(array[-array[i]]>0)
array[-array[i]]=-array[-array[i]];
}
}
else{
if(0>array[array[i]]){
System.out.println(array[i]);
}
else{
if(0 == array[array[i]])
array[array[i]] = -array.length;
else if(array[array[i]]>0)
array[array[i]]=-array[array[i]];
}
}
}
}

测试如下:
public static void main(String[] args) {
int[] array = new int[100];
/* array[0] = 1;
array[1] = 2;
array[2] = 0;
array[3] = 4;
array[4] = 0;*/
for(int i=0;i<100;i++)
array[i]=i;
array[5]=0;
array[1] = 1;
array[3] = 1;
array[89] = 80;
alg(array);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值