且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

LeetCode 217 Contains Duplicate(包含重复数字)(Vector、hash)

更新时间:2022-05-13 16:19:45

版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/50504102

翻译

给定一个整型数字数组,找出这个数组是否包含任何重复内容。

如果任何值出现了至少两次,那么返回真(true),

如果每个值都是互不相同的,那么返回假(false)。

原文

Given an array of integers, find if the array contains any duplicates. 

Your function should return true if any value appears at least twice in the array, 

and it should return false if every element is distinct.

分析

这次的题意比较简单,就不多阐述了。

我的第一反应还是比较原始的(我尽量在每次解题过程中描述我的思考过程),用std::find()函数在vector中查找是否有重复的值。

bool containsDuplicate(vector<int>& nums) {
    vector<int>::iterator temp;
    int num_to_find;
    for (vector<int>::iterator index = nums.begin(); index < nums.end(); ++index) {
        num_to_find = *index;
        temp = std::find(index + 1, nums.end(), num_to_find);
        if (temp != nums.end())
            return true;
    }
    return false;
}

然后放到LeetCode上试了一试,结果是超时了,好吧,毕竟测试用例中都是多少万级的数据。不急不急,如果用sort函数先排个序呢?

bool containsDuplicate(vector<int>& nums) {
sort(nums.begin(), nums.end());
    vector<int>::iterator temp;
    int num_to_find;
    for (vector<int>::iterator index = nums.begin(); index < nums.end(); ++index) {
        num_to_find = *index;
        temp = std::find(index + 1, nums.end(), num_to_find);
        if (temp != nums.end())
            return true;
    }
    return false;
}

发现并没有用,喔对了,即便排序了上面的代码还是对后面的所有数据都进行了一次扫描判断。

但是呢,既然排了序,直接用下一个数值和当前数值比较不就好了?

current == next  说明什么?重复了呗!
current < next 说明什么?我都排过序了啊,这不是妥妥的嘛?不用判断这个了。
current > next 说明什么?都说了已经排过序了,这可能吗!

那么,看代码……(我把index改成了it,只是为了让那一行显得短一点,两个变量的意义是一样的)

bool containsDuplicate(vector<int>& nums) {
    if (nums.size() <= 1)
        return false;
    sort(nums.begin(), nums.end());
    vector<int>::iterator temp;
    int num_to_find;
    for (vector<int>::iterator it = nums.begin(), temp = it + 1; it < nums.end(); ++it,++temp) {
        if (*temp == *it)   return true;
    }
    return false;
}

不过其实这里出现了两次temp:

temp = it + 1;
++ temp;

看起来还是比较麻烦的,还是改得清晰点:

bool containsDuplicate(vector<int>& nums) {
    if (nums.size() <= 1)
        return false;
    sort(nums.begin(), nums.end());
    vector<int>::iterator temp;
    int num_to_find;
    for (vector<int>::iterator it = nums.begin(); it < nums.end(); ++it) {
        temp = it + 1;
        if (*temp == *it) return true;
    }
    return false;
}

代码

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        if (nums.size() <= 1)
            return false;
        sort(nums.begin(), nums.end());
        vector<int>::iterator temp;
        int num_to_find;
        for (vector<int>::iterator it = nums.begin(); it < nums.end(); ++it) {
            temp = it + 1;
            if (*temp == *it) return true;
        }
        return false;
    }
};

进阶

我的代码是44ms,来看看大神写的36ms的是怎样的吧,加油!

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        if(nums.size() == 0)    return false;

        int min = nums[0], max = nums[0];
        for(auto n : nums){
            if(n > max)     max = n;
            if(n < min)    min = n;
        }

        int arr[max - min + 1] = {0};
        for(auto n : nums){
            ++arr[n - min];
        }

        for(int i = 0; i != (max - min + 1); ++i)
            if(arr[i] > 1)  return true;
        return false;
    }
};

有意思的是,我用sort函数来排序之后反而增加了4ms。

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        if (nums.size() == 0)    return false;
        sort(nums.begin(), nums.end());
        int min = nums[0], max = nums[nums.size() - 1];

        int arr[max - min + 1] = { 0 };
        for (auto n : nums) {
            ++arr[n - min];
        }

        for (int i = 0; i != (max - min + 1); ++i)
            if (arr[i] > 1)  return true;
        return false;
    }
};

hash

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        int count=1000;
        vector<int> hash[count];
        for(int i=0;i<nums.size();i++)
        {
            int index=(nums[i]>=0?nums[i]:-nums[i])%count;
            for(int j=0;j<hash[index].size();j++)
            {
                if(nums[i]==hash[index][j])
                    return true;
            }
            hash[index].push_back(nums[i]);
        }
        return false;
    }
};