找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内(题设要点)。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3
限制:
2 <= n <= 100000
方法一:哈希表(最自然,但是要额外空间)
最容易想到用哈希表判重,这种方法是最自然的。
分析:这种方法不修改原始数组,但是使用了 O(N) 空间,使用空间换时间,是最正常的思路,时间复杂度是O(N)。
方法二:排序(也比较容易想到,但是要排序,复杂度高)
排序以后,再遍历一遍就知道哪个重复了。
分析:这个方法其实比较容易想到,但是时间复杂度是 O(N log N),同时也修改了原始数组。
方法三:把数组视为哈希表(因为条件的缘故可以直接根据索引确定,这个方法重点理解)
程序实例:
1 import java.util.*; 2 3 public class Problem03 { 4 public static void main(String[] args) { 5 6 //方法4重点理解 7 int []nums=new int[]{2, 3, 1, 0, 2, 5, 3}; 8 9 System.out.println(solution3(nums)); 10 } 11 public static int solution(int []nums){ 12 ////使用map,时间复杂度O(n),空间复杂度O(n),不改变原数组 13 Map<Integer,Integer> map=new HashMap<>(); 14 for (int num : nums) { 15 if(!map.containsKey(num)) 16 map.put(num,1); 17 else 18 return num; 19 } 20 return -1; 21 } 22 public static int solution2(int []nums){ 23 ////使用set,时间复杂度O(n),空间复杂度O(n),不改变原数组 24 Set<Integer> set=new HashSet<>(); 25 for (int num : nums) { 26 if(!set.contains(num)) 27 set.add(num); 28 else 29 return num; 30 } 31 return -1; 32 } 33 public static int solution3(int []nums){ 34 //使用排序加循环,时间复杂度O(nlogn),空间复杂度O(1) 35 Arrays.sort(nums); 36 int first=nums[0]; 37 for (int i = 1; i < nums.length; i++) { 38 if(first==nums[i]) 39 return nums[i]; 40 first=nums[i]; 41 } 42 return -1; 43 } 44 public static int solution4(int []nums){ 45 //使用原地哈希(找到重复的数字就是发生了哈希冲突),时间复杂度O(n),空间复杂度O(1) 46 47 //如果没有重复数字,那么正常排序后, 48 // 数字i应该在下标为i的位置, 49 // 所以思路是重头扫描数组,遇到下标为i的数字如果不是i的话, 50 // (假设为m),那么我们就拿与下标m的数字交换。 51 // 在交换过程中,如果有重复的数字发生,那么终止返回ture 52 53 //{2, 3, 1, 0, 2, 5, 3},举例一步一步的走一遍 54 int temp; 55 for(int i=0;i<nums.length;i++){ 56 while (nums[i]!=i){ 57 if(nums[i]==nums[nums[i]]){ 58 //如果冲突 59 return nums[i]; 60 } 61 temp=nums[i]; 62 nums[i]=nums[temp]; 63 nums[temp]=temp; 64 } 65 } 66 return -1; 67 } 68 public static int solution5(int []nums){ 69 //使用桶排序的思想(本质是hash),时间复杂度O(n),空间复杂度O(n) 70 //题目给了数组值的范围(小于数组长度),所以不会越界! 71 int[] arr = new int[nums.length]; 72 for(int i = 0; i < nums.length; i++){ 73 arr[nums[i]]++; 74 if(arr[nums[i]] > 1) return nums[i]; 75 } 76 return -1; 77 } 78 79 80 }
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof