剑指 Offer 03. 数组中重复的数字
剑指 Offer 03. 数组中重复的数字

对于此题,可以有几种不同的考虑,如果可以看出这是一类频率统计题,容易联系到哈希表,所以第一种方法也是比较容易想到的办法就是用哈希表来统计词频,这里由于数据范围可确定(0-n-1),可以用数组来简化一些代码上的书写,这种方法时间复杂度为\(O(n)\),空间复杂度为\(O(n)\)。
class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
int[] map = new int[n];
for(int num : nums) {
map[num]++;
if(map[num] > 1) return num;
}
return 0;
}
}
以上是基于词频的角度考虑,再考虑不需要新空间的算法,若我们将数组排序,如果有重复的数字,那么它们将会在相邻位置,同样可以做到找出重复数字的目的。时间复杂度\(O(nlogn)\),空间复杂度\(O(1)\)。
class Solution {
public int findRepeatNumber(int[] nums) {
Arrays.sort(nums);
for (int i = 1; i < nums.length; i++) {
if (nums[i] == nums[i - 1])
return nums[i];
}
return -1;
}
}
再考虑空间复杂度为\(O(1)\)且时间复杂度能够更低的算法。
我们可以发现给定的数据范围为\(0-n-1\)。若我们将对应的索引放置在它的对应位置,如果没有重复元素,那么每个元素都会被放在它的索引位置,如果有重复元素,则放置时会发现该位置已经有元素了。
class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
for(int i = 0; i < n; i++) {
while(nums[i] != i) {
if(nums[nums[i]] == nums[i]) return nums[i];
int tmp = nums[i];
nums[i] = nums[tmp];
nums[tmp] = tmp;
}
}
return -1;
}
}

浙公网安备 33010602011771号