题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2
思路
思路1:排序。将输入的数组排序后判断相邻位置是否存在相同的数字。 (时间复杂度:O(nlogn) ;空间复杂度:O(1))
思路2:哈希表。使用HashMap或HashSet。 (时间复杂度:O(n) ;空间复杂度:O(n))
--------以下思路3 和 思路4 利用到题中已知条件“数组的长度为 n 且所有数字都在 0 到 n-1 的范围内”---------
思路3:辅助数组。逐一把原数组A中的每个数字匹配辅助数组B中的下标,首次匹配,B中对应元素+1,如果某次发现B中对应元素不为0,说明重复了。 (不会修改输入数组,但需要用辅助空间, 时间复杂度:O(n) 、空间复杂度:O(n))
思路4:交换归位。把扫描的每个数字(如数字m)放到其对应下标(m下标)的位置上,若同一位置有重复,则说明该数字重复。 (不需要辅助空间,但会修改输入数组, 时间复杂度:O(n) 、空间复杂度:O(1))
解法1(使用哈希表)
import java.util.*; public class Solution { // 使用HashMap public boolean duplicate(int numbers[],int length,int [] duplication) { if (numbers == null || length == 0) return false; HashMap<Integer,Integer> map = new HashMap<>(); for (int num : numbers){ map.put(num,map.getOrDefault(num,0) + 1); if (map.get(num) == 2){ duplication[0] = num; return true; } } return false; } // 使用HashSet public boolean duplicate(int numbers[],int length,int [] duplication) { if (numbers == null || length == 0) return false; HashSet<Integer> set = new HashSet<>(); for (int num : numbers){ if (set.contains(num)){ duplication[0] = num; return true; }else{ set.add(num); } } return false; } }
解法2(辅助数组)
import java.util.*; public class Solution { public boolean duplicate(int numbers[],int length,int [] duplication) { if (numbers == null || length == 0) return false; int[] room = new int[length]; //Arrays.fill(room,0); // 辅助数组初始化为0,不加这句也可以 for (int i = 0; i < length; i++) { if (room[numbers[i]] == 0){ room[numbers[i]]++; }else{ duplication[0] = numbers[i]; return true; } } return false; } }
☆解法3(交换归位)
public class Solution { public boolean duplicate(int numbers[],int length,int [] duplication) { if (numbers == null || length == 0) return false; for (int i = 0; i < length; i++) { while (numbers[i] != i){ // 直到当前i位置 == nums[i] if (numbers[numbers[i]] == numbers[i]){ duplication[0] = numbers[i]; return true; }else{ // swap int temp = numbers[i]; numbers[i] = numbers[temp]; numbers[temp] = temp; } } } return false; } }