题目:一个长度为n的数组中元素都是0~n-1的,且数组中有重复元素,要求返回任意一个重复的数。
public int findRepeatNumber(int[] nums)
思路:1.用set(HashSet)来做。重复的元素都可以考虑用set做。
把元素放到set里,直到遍历到重复的元素。时间复杂度O(n)(遍历一遍,hashSet的add和contains都是O(1),因为hashSet是基于哈希表实现的),空间复杂度为O(n)。
2.边遍历边根据下标与值的关系进行交换。(先举有重复和无重复的例子,得到下标与值的对应关系)。每次交换就会凑成一对,当到达重复的元素的下标时就发现它重复了。
//set实现(重复的问题都可以用set去解决)
public int findRepeatNumber(int[] nums){
if(nums == null || nums.length == 0){
return -999;
}
//HashSet是基于哈希表实现的,add remove contains都是O(1)
Set<Integer> set = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
if(!set.contains(nums[i])){
set.add(nums[i]);
}else{
return nums[i];
}
}
return -999;
}
//边遍历边根据下标和值的对应进行交换
public int findRepeatNumber(int[] nums){
if(nums == null || nums.length == 0){
return -999;
}
for (int i = 0; i < nums.length; i++) {
//处理下标和值相等的情况
if(i == nums[i]){
continue;
}
if(nums[nums[i]] != nums[i]){
//交换后原nums[i]的下标和值就凑成了一对
int temp = nums[i];
nums[i] = nums[nums[i]];
//nums[i]已经被修改了,不能再使用,用temp
nums[temp] = temp;
}else{
//这种情况只能是重复的数
return nums[i];
}
}
//没找到
return -999;
}