题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
解析
这题较为简单,只需要使用Set保存数组中每一个数字,由于Set的特性不能存在重复元素,所以在数组遍历过程中发现Set中已经存在当前数字,说明找到了第一个重复的数字,返回即可。
原地交换
如果数组中没有重复数字,正常排序后,数字i在下标为i的位置, 即nums[i]=i, 所以从头扫描数组,遇到下标为i的数字如果不是i, 交换nums[i] 和 nums[nums[i]]。在交换过程中,如果有重复的数字发生,即nums[i] === nums[nums[i]], 循环终止返回 true
参考代码
使用Set
时间复杂度: O(N)
空间复杂度: O(N)
/**
* @param {number[]} nums
* @return {number}
*/
var findRepeatNumber = function(nums) {
// 声明Set, 保存遍历过的每一个数字
const set = new Set();
// 遍历数组
for (let i = 0; i < nums.length; i++) {
// 当发现 set 中已经存在当前数字
if (set.has(nums[i])) {
// 返回第一个重复的数字
return nums[i];
}
// 把当前数字添加到set
set.add(nums[i]);
}
};
原地交换
时间复杂度: O(N)
空间复杂度: O(1)
/**
* @param {number[]} nums
* @return {number}
*/
var findRepeatNumber = function(nums) {
let i = 0;
while (i < nums.length) {
if (nums[i] === i) {
i++;
continue;
}
if (nums[i] === nums[nums[i]]) {
return nums[i];
}
// 交换nums[i] 和 nums[nums[i]];
let tmp = nums[i];
nums[i] = nums[tmp];
nums[tmp] = tmp;
}
return -1;
};