【剑指Offer-数组】面试题3:数组中的重复数字

题目描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

思路1

先排序,然后遍历数组,如果 nums[i]==nums[i+1],则说明 nums[i] 重复,返回 nums[i] 即可。代码如下:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end());

        for(int i=0; i<nums.size()-1; i++){
            if(nums[i]==nums[i+1]) return nums[i];
        }
        return 0;
    }
};
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)

思路2

使用哈希表。从头到尾扫描数组,每扫描到一个数字时,就用O(1)的时间来判断哈希表中是否包含了该数字。如果包含,就找到了一个重复数字;如果没有包含,就把该数字加入到哈希表中。

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        vector<bool> hash(nums.size(), false);

        for(int i=0; i<nums.size(); i++){
            if(hash[nums[i]]==true) return nums[i];
            else hash[nums[i]] = true;
        }
        return 0;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

思路3

使用和缺失的第一个正数类似的方法。遍历 nums,并将 nums[nums[i]] 设为 -nums[nums[i]],这样,在遍历的过程中,如果我们先 nums[nums[i]] 为负数,则说明 nums[i] 是重复的。

这个方法还有一个问题要解决,就是 0 的问题。我们设置一个标志 findZero 表示是否找到了 0,如果第一次找到 0,则将 findZero 设为 true,如果我们在找到 0,则将 0 的下标返回即可。代码如下:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        bool findZero = false;
        for(int i=0; i<nums.size(); i++){
            int idx = abs(nums[i]);
            if(nums[idx]==0){
                if(findZero==true) return idx;
                else findZero = true;
            }else if(nums[idx]<0){
                return idx;
            }else{
                nums[idx] = -nums[idx];
            }
        }
        return 0;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

思路4

遍历数组,如果 nums[i]==i,说明 i 没有缺失,判断下一个元素。如果 nums[i]!=i,则交换 nums[i] 和 nums[nums[i]],如果在交换的过程中发现 nums[i]==nums[nums[i]],则返回 nums[i]。代码如下:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        for(int i=0; i<nums.size(); i++){
            if(nums[i]!=i){
                while(nums[i]!=i){
                    if(nums[i]==nums[nums[i]]) return nums[i];
                    else swap(nums[i], nums[nums[i]]);
                }
            }
        }
        return 0;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
posted @ 2020-01-07 16:53  Flix  阅读(155)  评论(0编辑  收藏  举报