剑指offer JZ3-数组中重复的数字
![在这里插入图片描述](https://img-blog.csdnimg.cn/370808c84a1946e4ac6632eb5db258f2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARGFpX2RhaV9kZV8=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
题目
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1:
数据范围:0<=n<=1000
进阶:时间复杂度O(n) ,空间复杂度O(n)
示例一
输入:[2,3,1,0,2,5,3]
返回值:2
说明:2或3都是对的
解法一
public static int duplicate(int[] numbers) {
for (int i = 0; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[i] == numbers[j]) {
return numbers[i];
}
}
}
return -1;
}
简单说明
思想简单,就是拿数组中第一个元素和他身后所有元素比较,若找到和第一个元素相等的元素,则返回第一个元素值;若没有找到和第一个元素相等的,则拿数组中第二个元素和他身后所有元素比较,以此类推。可以解题,但时间复杂度为O(n^2)。
解法二:
public static int duplicate(int[] numbers) {
HashSet<Integer> hashSet = new HashSet<Integer>();
for (int i = 0; i < numbers.length; i++) {
if (!hashSet.add(numbers[i])) {
return numbers[i];
}
}
return -1;
}
简单说明:
利用了Java中set集合去重的特点。解释一点:!hashSet.add(numbers[i])
。我们阅读JDK中HashSet的add()方法。
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
注意注释的第5行,大致意思是说,如果集合中已包含此元素,集合保持不变,add()返回false。add()返回false就表示set集合中已包含此元素,此元素为重复元素。!hashSet.add(numbers[i])
的值为true。返回此元素值。