找出数组中重复的数字

找出数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

题解:题目中的数字范围为0~1,因此有一个最简单的思路:以数组nums中的长度创建数组,nums中的数值为下标,不会越界。

第一种:直接排序,有数值相等的时候那么就是重复的数字。

第二种:哈希表的思想,将nums数组中相应的数字放入辅助数组中以该数字为下标,并且数值加1,当某个位置的值大于1的时候,说明该数字重复。

第三种:第二种方法的改进,如题解所述,直接将一个数放入数组中相应的下标位置,当该值与下标位置的值相等的时候,说明该值重复了。

例如:数组[0,0,1,3],第一个0的位置正确,第二个0的下标为1,但是该值本身应该放置下标为0的位置,但是该位置已经有0了,就会形成 i == nums[nums[i]],说明存在重复数值的情况。

分析:第三种方法的时间复杂度为O(n)。如代码中,当i == k的时候进入了while循环,那么一定存在k之后的某个时候是不会再次进入while中。

完整代码

 1 /**
 2  * @author: wooch
 3  * @create: 2020/02/14
 4  */
 5 
 6 import java.util.Arrays;
 7 
 8 /**
 9  * 找出数组中重复的数字。
10  * 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。
11  * 数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。
12  * 请找出数组中任意一个重复的数字。
13  */
14 public class P3_FindRepeatNumber {
15     public int findRepeatNumber(int[] nums) {
16         // Arrays.sort(nums);
17         // int res = -1;
18         // for (int i = 0; i < nums.length; i++) {
19         //     if (nums[i] == res) {
20         //         return res;
21         //     } else {
22         //         res = nums[i];
23         //     }
24         // }
25         // return res;
26 
27         // int len = nums.length;
28         // int[] arr = new int[len];
29         // for (int i = 0; i < len; i++) {
30         //     arr[nums[i]]++;
31         //     if (arr[nums[i]] > 1) {
32         //         return nums[i];
33         //     }
34         // }
35         // return 0;
36 
37 
38         for (int i = 0; i < nums.length; i++) {
39             while (i != nums[i]) {
40                 if (nums[i] == nums[nums[i]]) {
41                     return nums[i];
42                 } else {
43                     swap(nums, i, nums[i]);
44                 }
45 
46             }
47         }
48         return -1;
49     }
50 
51     private void swap(int[] nums, int i, int j) {
52         int temp = nums[i];
53         nums[i] = nums[j];
54         nums[j] = temp;
55     }
56 }
原文地址:https://www.cnblogs.com/baishouzu/p/12308106.html