1.暴力写法
class Solution {
public int findRepeatNumber(int[] nums) {
int[] a = new int[100000];
int max = 0,sum;
for(int i = 0; i < nums.length;i++){
sum = nums[i];
a[sum]++;
if(a[sum]>=2){
max = sum;
}
}
return max;
}
}
1.时间O(n)
2.空间O(n)
2.哈希表写法
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> set = new HashSet<Integer>();
int repeat = -1;
for (int num : nums) {
if (!set.add(num)) {
repeat = num;
break;
}
}
return repeat;
}
}
时间复杂度:O(n)。
遍历数组一遍。使用哈希集合(HashSet),添加元素的时间复杂度为 O(1),故总的时间复杂度是 O(n)。
空间复杂度:O(n)。不重复的每个元素都可能存入集合,因此占用 O(n) 额外空间。
3.数组写法
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for(int i = 0;i < nums.length ;i++ ){
if(set.contains(nums[i])){
return nums[i];
}
set.add(nums[i]);
}
return -1;
}
}
时间复杂度是 O(n)
空间复杂度是 O(n)
可以看出,时间复杂度和空间复杂度都是和用哈希表的解决方案是一样的。但是使用数组绝对会有性能的提高,主要表现在如下的两个方面:
1.哈希表 (HashSet) 底层是使用数组 + 链表或者红黑树组成的,而且它的数组也是用不满的,有加载因子的。所以使用数组来代替哈希表,能节省空间
2.哈希表在判重的时候需要经过哈希计算,还可能存在哈希冲突的情况,而使用数组则可以直接计算得到 index 的内存位置,所以使用数组访问性能更好。
4.最优解(原地交换)
class Solution {
public int findRepeatNumber(int[] nums) {
for (int i = 0; i < nums.length; i++) {
while (i != nums[i]) {
if (nums[i] == nums[nums[i]]) {
return nums[i];
}
int t = nums[nums[i]];
nums[nums[i]] = nums[i];
nums[i]= t;
}
}
return -1;
}
}
时间复杂度是 O(n)
空间复杂度是 O(1)