剑指 Offer 03 数组中重复的数字
链接: https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
字节暑期实习一面的时候被问到这道题,感觉还挺简单的,第一个想法就是使用HashMap中的containsKey来解决这个问题。然后就写出了如下代码:
class Solution {
public int findRepeatNumber(int[] nums) {
HashMap<Integer,Integer> map = new HashMap();
for(int i = 0; i < nums.length;i++){
if(map.containsKey(nums[i])){
return nums[i];
}
map.put(nums[i],0);
}
return -1;
}
}
面试官问我时间复杂度和空间复杂度之后我就预感要糟.,果然接下来的问题就是还有没有别的方法…苦思冥想也没想出来还有什么好方法,不过还是过了一面(结果二面就挂了…)。看了题解之后才发现其实题目中有条件是可以利用的…
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。
这个题目可以使用交换来解决,即将对应数字移动到其对应索引位置,如果移动后值相等则表示该数字重复,而且题目中并没有限制一定要输出哪个数字,所以只要有就可以输出。代码如下:
class Solution {
public int findRepeatNumber(int[] nums) {
int temp = 0;
int i = 0;
while(i < nums.length){
if(nums[i] == i){
i++;
continue;
}
if(nums[nums[i]] == nums[i]){
return nums[i];
}
int tmp = nums[i];
nums[i] = nums[tmp];
nums[tmp] = tmp;
}
return -1;
}
}
这样时间复杂度虽然还是O(N),但空间复杂度就是O(1)了!