谷歌面试题--一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间

该博客详细解析了一道谷歌面试题,题目要求在大小为n且数值范围在[0, n-1]的数组中,寻找至少一个重复元素,同时满足O(1)空间复杂度和O(n)时间复杂度。通过基数排序的思想,通过不断交换数组元素来定位重复值,最终找到重复的元素2。" 102621905,8750163,Python伪装技巧:逃过反爬虫的10行代码,"['Python', '爬虫技术', '网页抓取']

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

这是一道谷歌的面试题,一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间

这题目的难点就是他的限制条件,只能是o(1)的空间和o(n)的时间,所以我们不能使用hashmap来统计重复的值,但是可以使用Hashmap的思想,

根据题目,我们可以把给定的数组当做一个hashmap,利用基数排序的方式找到重复的数。

分析思路如下:

下面以2415761902这十个数为例,展示下如何用基数排序来查找重复元素。

下标

  0

  1

  2

  3

  4

  5

  6

  7

  8

  9

数据

  2

  4

  1

  5

  7

  6

  1

  9

  0

  2

1)由于第0个元素a[0] 等于2不为0,故交换a[0]a[a[0]]即交换a[0]a[2]得:

下标

  0

  1

  2

  3

  4

  5

  6

  7

  8

  9

数据

  1

  4

  2

  5

  7

  6

  1

  9

  0

  2

2)由于第0个元素a[0] 等于1不为0,故交换a[0]a[a[0]]即交换a[0]a[1]得:

下标

  0

  1

  2

  3

  4

  5

  6

  7

  8

  9

数据

  4

  1

  2

  5

  7

  6

  1

  9

  0

  2

3)由于第0个元素a[0] 等于4不为0,故交换a[0]a[a[0]]即交换a[0]a[4]得:

下标

  0

  1

  2

  3

  4

  5

  6

  7

  8

  9

数据

  7

  1

  2

  5

  4

  6

  1

  9

  0

  2

4)由于第0个元素a[0] 等于7不为0,故交换a[0]a[a[0]]即交换a[0]a[7]得:

下标

  0

  1

  2

  3

  4

  5

  6

  7

  8

  9

数据

  9

  1

  2

  5

  4

  6

  1

  7

  0

  2

5)由于第0个元素a[0] 等于9不为0,故交换a[0]a[a[0]]即交换a[0]a[9]得:

下标

  0

  1

  2

  3

  4

  5

  6

  7

  8

  9

数据

  2

  1

  2

  5

  4

  6

  1

  7

  0

  9

6)由于第0个元素a[0] 等于2不为0,故交换a[0]a[a[0]]即交换a[0]a[2],但a[2]也为2a[0]相等,因此我们就找到了一个重复的元素——2

下标

  0

  1

  2

  3

  4

  5

  6

  7

  8

  9

数据

  2

  1

  2

  5

  4

  6

  1

  7

  0

  9


由此我们可以写出代码如下:

package google;

public class RepeatNumber {

	/**
	 * 一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间。
	 */
	public static void swap(int i,int j ,int num[]){
		int temp;
		temp=num[i];
		num[i]=num[j];
		num[j]=temp;
	}
	public static int findRepeatNumber(int num[],int n){
		int repeatNum=-1;
		for(int i=0;i<n;i++){
			while(i!=num[i]){
				if(num[i]==num[num[i]])
					return num[i];
				swap(num[i],num[num[i]],num);
			}
		}
		return repeatNum;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int num[]={0,1,2,2,4,5,6,6};
		int repNum=findRepeatNumber(num,8);
		if(repNum==-1)
			System.out.println("没有重复的数");
		else
			System.out.println("重复的数为"+repNum);
		
	}

}
该本章是在总结MoreWindows的基础之上写的,感谢MoreWindows提供的思路,原文出处http://blog.youkuaiyun.com/morewindows/article/details/8204460

og



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值