1.题目
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
2.解法1:HashSet
使用HashSet,HashSet的时间复杂度O(1),整体时间复杂度O(n),占用空间O(n)。
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param numbers int整型一维数组
* @return int整型
*/
public int duplicate(int[] numbers) {
// write code here
if(numbers == null || numbers.length == 0){
return -1;
}
HashSet<Integer> container = new HashSet<>();
for (int n : numbers) {
if (container.contains(n)) return n;
container.add(n);
}
return -1;
}
}
3.解法2:用数组替换HashSet
数组的下标查找时间复杂度O(1),整体时间复杂度O(n),占用空间O(n)。
public class Solution2 {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param numbers int整型一维数组
* @return int整型
*/
public int duplicate(int[] numbers) {
// write code here
if(numbers == null || numbers.length == 0){
return -1;
}
int[] containers = new int[numbers.length];
for(int n:numbers){
containers[n] += 1;
if(containers[n]>1) return n;
}
return -1;
}
}
4.解法3:原地交换
原地交换,如果发现坑位被占用,则说明冲突。
public class Solution3 {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param numbers int整型一维数组
* @return int整型
*/
public int duplicate(int[] numbers) {
// write code here
if(numbers == null || numbers.length == 0){
return -1;
}
for (int i = 0; i < numbers.length; i++) {
int a = numbers[i];
if(a!=i) {
if(numbers[a]==a) return a;
swap(a,i,numbers);
}
}
return -1;
}
public void swap(int a,int i,int[] numbers) {
int temp = numbers[a];
numbers[a] = numbers[i];
numbers[i] = temp;
}
}
总结
通过HashSet可以简化查找复杂度。也可以原地,节省空间。
算法系列在github上有一个开源项目,主要是本系列博客的demo代码。https://github.com/forestnlp/alg
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。