剑指Offer题4 —— public static void main (String[] args) throws java.lang.Exception { int[不修改数组找出重复数字

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

方案一:暴力解法

将数组中的元素两两相比,最差情况时间复杂度是O(n²). 

方案二:使用Set

创建一个大小为n的Set,每次向Set中插入一个数字,如果插入错误,说明这个数字是重复的,输出这个数字即可。此方案时间复杂度是O(n),空间复杂度是O(n),代码如下:

public static void main (String[] args) throws java.lang.Exception{
	int[] array = {1,2,3,4,5,6,3,2};
	HashSet<Integer> set = new HashSet();
	for(int i : array) {
		if(!set.add(i)) {
			System.out.println(i);
			return;
		}		
	}
}

方案三:分析数组规律

假设数组长度为n,且数组中所有数字都在1~n的范围内,而且元素不重复,那么每个1~n的每个数字都会出现一次,也就是1~n的范围内有n个数字,应为现在数组长度为n+1,所以必然存在1~n范围内的数字大于n。

假设n为8,我们把1~8分成两组,{1, 2, 3, 4}是一组,{5, 6, 7, 8}是一组,那么必然存在1~4范围内的数字个数大于4或者5~8范围内的数字个数大于4。

数组{2, 3, 5, 4, 3, 2, 6, 7}中1~4范围内的数字个数为5,所以我们再把1~4分钟两组,{1, 2}是一组,{3, 4}是一组,再重复上述逻辑。这样时间复杂度为O(n√n),代码如下:

import java.util.*;
import java.lang.*;

class

猜你喜欢

转载自blog.csdn.net/kanglupeng/article/details/104205787