题目要求
数组中重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。
数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。
请找出数组中任意一个重复的数字。
例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路
1.先将数组进行排序,然后在排序后的数组中查找重复的数据,比较容易,只需要从头到尾扫描数组就行了。但是这个排序数组的时间复杂度是O(nlogn).
2.使用哈希表
先遍历数组,当扫描到一个数字的时候,都可以用O(1)的时间来判断哈希表是否包含了该数字,如果不存在,就加入此数字到哈希表中。如果存在,就返回;算法的时间复杂度。是O(n) ,但是以一个大小为O(n)的哈希表为代价的
3:基于使用哈希表的缺点,目标在于空间复杂度在O(1)的算法。如果这个数组中没有重复的数据的话,那么当数组排序之后,数字 i 将出现在下标位置为 i 的位置,由于数组中有重复的数字,有些位置可能存在多个数字,同时,可能某些位置没有数字
让我们重排这个数组,从头到尾依次扫描这个数组中的每一个数字。当扫描到下标为i的数组时,首先比较这个数字(A[i])是不是等于 i,如果相等,则接着扫描下一个数字,如果不相等,则再拿它和第(A[i])个位置的数字进行比较,如果此时相等,那么就找到了一个重复的数字。如果不相等的话,那就把第i个位置的数字和第A[i] 个数字进行交换,知道找到一个重复的数字位置。
代码实现
package com.offer.test;
/**
* 在一个长度为n的数组里的所有数字都在0到n-1的范围内。
* 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。
* 请找出数组中任意一个重复的数字。
* 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
*
* @author zhouwenchen@021.com
* @date 2019年6月11日 下午7:38:46
*/
public class DuplicateArray {
public static boolean duplicate(int[] arr) {
// 条件判断,数组是否为空
if (arr.length <= 0 || arr == null) {
return false;
}
// 判断数组中数据是否满足条件要求(取值范围在0-n-1之间)
for (int i = 0; i < arr.length; i++) {
if (arr[i] > arr.length || arr[i] < 0) {
return false;
}
}
for (int i = 0; i < arr.length; i++) {
while (i != arr[i]) {
// 替换
if (arr[i] == arr[arr[i]]) {
System.out.println(arr[i]);
return true;
} else {
int temp = arr[i];
arr[i] = arr[arr[i]];
arr[temp] = temp;
}
}
}
return false;
}
public static void main(String[] args) {
int[] arr = new int[] { 2, 3, 1, 0, 2, 5, 3 };
boolean b = duplicate(arr);
System.out.println(b);
}
}