面试题3-1:数组中重复的数字


1.题目描述

在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7,的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数组2或者3。

2.分析边界条件及测试用例

  1.考虑输入数组为空,测试用例为{};

  2.考虑输入数组含有大于数组规模的数,测试用例为{0,1,2,3,5};

  3.考虑输入数组不重复,包含两种可能(都是小于数组规模的数,存在大于数组规模的数(2)

  中包含),测试用例为{0,1,2,3,4};

3.三种解法

1.数组排序再扫描

将数组进行排序,从排好序的数组的开头进行遍历,记录当前位置与其之前位置的数,进行比较,若相等则输出该数,否则判断下一位数。

 1     public static int getRepeatNumber(int[] array) {
 2         // Judge the boundary of this problem
 3         int len = array.length;
 4         if (len == 0) {return -1;}
 5 
 6         // solution 1 sort array then search from first to end
 7         Arrays.sort(array);
 8         if (array[len - 1] >= len) {
 9             return -1;
10         } else {
11             int temp = array[0];
12             int i = 1;
13             for(; i < len; i++) {
14                 if (temp == array[i]) {
15                     break;
16                 } else {
17                     temp = array[i];
18                 }
19             }
20             if (i == len) {
21                 return -1;
22             } else {
23                 return array[i];
24             }
25         }
26     }

复杂度分析:时间复杂度O(nlogn),空间复杂度O(1)。

2.哈希表

对数组元素进行遍历,每次判断哈希表中是否有该元素,若有,输出此重复元素,若最后哈希表中元素数量与数组规模相等,表明无重复元素。

 1     public static int getRepeatNumber(int[] array) {
 2         // Judge the boundary of this problem
 3         int len = array.length;
 4         if (len == 0) {return -1;}
 5         Set<Integer> set = new HashSet<>();
 6         int i = 0;
 7         for(; i < len; i++) {
 8             if (array[i] >= len) {
 9                 return -1;
10             } else {
11                 if (set.contains(array[i])) {
12                     break;
13                 } else {
14                     set.add(array[i]);
15                 }
16             }
17         }
18         if (i == len) {
19             return -1;
20         } else {
21             return array[i];
22         }
23     }

复杂度分析: 时间复杂度O(n),空间复杂度O(n)。

3.重排数组

从头到尾依次扫描数组中每一个数字。当扫描到第i个元素时,比较该位置数值m是否等于i。若是,接着扫描下一个数字;否则,将其与第m个数字进行比较。若相等,则返回该重复数字;否则,交换两个数字,继续重复前面的过程。

 1     public static int getRepeatNumber(int[] array) {
 2         // Judge the boundary of this problem
 3         int len = array.length;
 4         if (len == 0) {return -1;}
 5         for(int i = 1; i < len;) {
 6             if (array[i] >= len) {
 7                 return -1;
 8             } else {
 9                 if (array[i] == i) {
10                     i++;
11                 } else {
12                     if (array[i] == array[array[i]]) {
13                         return array[i];
14                     } else {
15                         int tmp = array[i];
16                         array[i] = array[array[i]];
17                         array[array[i]] = tmp;
18                     }
19                 }
20             }
21         }
22         return -1;
23     }

复杂度分析: 时间复杂度O(n),空间复杂度O(1)。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM