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

111 阅读1分钟

题目

找出数组中重复的数字。

在一个长度为 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;
};

原题链接

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