数组中重复的数字

找出数组中重复的数字。


在一个长度为 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



原文地址:https://www.cnblogs.com/treasury/p/12594214.html