找出数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

注意:如果某些数字不在 0 ~ n 的范围内,或数组中不包含重复数字,则返回 -1;

样例:

输入: [2, 3, 1, 0, 2, 5, 3]

输出:2 或 3


方法一:使用哈希表

遍历该数组,如果某元素出现两次,则return 该元素。


方法二:原地置换算法

具体的步骤如下:

  • 从前往后遍历数组中的所有数,假设当前遍历到的数是 nums[i]=x,那么:
  • 如果x != i && nums[x] == x,则说明 x 出现了多次,直接返回 x 即可;
  • 如果nums[x] != x,那我们就把 x 交换到正确的位置上,交换完之后如果nums[i] != i,则重复进行该操作;
  • 由于每次交换都会将一个数放在正确的位置上,所以swap操作最多会进行n次,不会发生死循环;
  • 循环结束后,如果没有找到任何重复的数,则返回−1。

时间复杂度分析:

每次swap操作都会将一个数放在正确的位置上,最后一次swap会将两个数同时放到正确位置上,一共只有 n个数和 n个位置,所以swap最多会进行 n−1次。所以总时间复杂度是 O(n)。

代码如下:

class Solution {
public:
    int duplicateInArray(vector<int>& nums) {
        int n = nums.size();
        for (int x : nums) {
            if (x < 0 || x >= n) return -1;
        }
        
        for (int i = 0; i < n; i++) {
            while (nums[i] != i) {
                if (nums[i] == nums[nums[i]]) return nums[i];
                swap (nums[i], nums[nums[i]]);
            } 
        }
        
        return -1;
    }
};

 

posted @ 2022-11-16 16:17  !&&||  阅读(174)  评论(0)    收藏  举报