题目:
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例:输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3
class Solution {
public int findRepeatNumber(int[] nums) {
HashSet<Integer> l =new HashSet<>();
for(int i:nums){
if(!l.contains(i))
l.add(i);
else
return i;}
return 0;
}
}
分析:使用ArrayList则会超时,因为ArrayList是顺序结构且允许数据重复,HashSet则是无顺序结构,不允许重复数据的存在。详解如下:
ArrayList:
由于数据中存在重复元素,所以使用contains()
方法,但是,ArrayList
的contains()
方法会调用其indexOf()
方法,在indexOf()
方法里边,有一个for循环,所以,ArrayList
的contains()
方法的时间复杂度是O(n)。
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
HashSet:
对于HashSet
,它的add()
方法会自动去重,它调用的是一个map
的put
方法,其时间复杂度是O(1)
。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
结论:
所以,在大量的数据的时候,不要使用List
的contains()
方法,其效率很低,可以考虑使用Set
来实现。