Loading

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

题目

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

思路1(哈希表)

  • 依次遍历数组,将元素存入哈希表中,如果哈希表中已经存在,那么就找到重复的数

代码

class Solution {
    public int findRepeatNumber(int[] nums) {
        HashSet<Integer> set = new HashSet<>();
        for (int n : nums) {
            if (!set.add(n)) {
                return n;
            }
        }
        return -1;
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\)
  • 空间复杂度:\(O(N)\)

思路2(原地交换)

  • 由于数组是无序的,我们可以遍历数组,将数组的值放到对应的索引位置上,与它进行交换
  • 当出现索引位置上的值已经有序,而当前的数字又需要放到该位置上,因此冲突,就找到了重复的值
  • 例如:[2, 3, 1, 0, 2, 5, 3]
    1. 2不等于当前索引值0,因此放到索引2上,然后将位置的1放到当前位置,此时:[1, 3, 2, 0, 2, 5, 3]
    2. 因为1还是不等于当前索引值0,所以将13交换,此时:[3, 1, 2, 0, 2, 5, 3]
    3. 因为3又不等于索引值0,所以将30进行交换,此时:[0, 1, 2, 3, 2, 5, 3]
    4. 然后0等于索引0,然后下一个1也等于索引值12也等于索引值23也等于索引值3
    5. 接下来到了第五个数字,2不等于索引值4,所以要放到索引为2的位置上,但是,此时索引2位置上已经是正确的2了,因此可以知道该数字重复了
    6. 最后找到重复的数字2了~

代码

class Solution {
    public int findRepeatNumber(int[] nums) {
        int length = nums.length;
        int index = 0;

        while (index < length) {
            // 如果索引和数组的值相等才进行后一位的调整
            if (nums[index] == index) {
                index++;
                continue;
            }

            // 能到这里说明当前的值不在对应的索引位置上,但是如果对应的索引位置上已经存在了值,就说明该数字重复了
            if (nums[nums[index]] == nums[index]) {
                return nums[index];
            }

            // 将当前位置的值放到对应的索引位置进行交换
            int afterIndex = nums[index];
            nums[index] = nums[afterIndex];
            nums[afterIndex] = afterIndex;
        }

        return -1;
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\),只需遍历一次数组
  • 空间复杂度:\(O(1)\),在原数组操作,不需要额外的空间
posted @ 2021-11-12 01:01  linzeliang  阅读(56)  评论(0)    收藏  举报