217. Contains Duplicate

问题:
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.

我的解答:

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        if(nums.size()<2) return false;
          unordered_map<int, int> count;
    for (int i = 0; i < nums.size(); i++)
    {
        if (++count[nums[i]] == 2)
            return true;
    }
    return false;
    }
};

ac:48ms beats 48.09%

解释:拿到这道题,很明显就是用哈希表来做,看看有没有表内某个数据对应的个数超过二的。
这个做法很容易想到,所以没什么好说的,后来看一下别人做的24ms的做法,如下。

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        int length = nums.size();
        bool *hashTable = (bool*)calloc(length, sizeof(bool));
        int *numTable = (int*)calloc(length,sizeof(int));
        for(vector<int>::iterator iter = nums.begin(); iter!= nums.end(); iter++){
            int assign = *iter % length;
            while(assign < 0 || hashTable[assign] && numTable[assign]!= *iter)assign=(assign+1)%length;
            if(hashTable[assign])return 1;
            else {hashTable[assign]=1;numTable[assign]=*iter;}
        }
        return 0;
    }
};

calloc是一个ISO C函数函数原型:void *calloc(size_t n, size_t size);
功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
与malloc的区别:
calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。一般使用后要使用 free(起始地址的指针) 对内存进行释放,不然内存申请过多会影响计算机的性能,以至于得重启电脑。如果使用过后不清零,还可以使用指针对该块内存进行访问。
这里的iterator是vector容器类的迭代器。对于每种容器类(vector,list,deque)来说,迭代器可能是指针,而对另一个迭代器,可能是对象。不管实现方式如何,迭代器都将提供所需的操作,如*和++(有些类需要的操作比其他类多)。其次,每个容器类都有一个超尾标记,当迭代器递增到超越容器的最后一个值后,这个值将被赋给迭代器。每个容器类都有begin()和end()方法,他们分别返回一个指向容器的第一个元素和超尾位置的迭代器。每个容器类都使用++操作,让迭代器从指向第一个元素逐步指向超尾位置,从而遍历容器中的每一个元素。

&&的优先级高于||

这个算法的基本思路我考虑了很久。是这样的。定义一个hashtable,和一个numtable。这样就有nums,hashtable,numtable三个了。nums存原始数据,hashtable里存有没有被访问过的信息(1 或0),numtable存hashtable对应的数,即该数有没有被访问过。然后通过assign的对length取余操作,同时在hashtable和numtable中循环遍历被访问过而且访问的值是为当前我们审阅的*iter的值。直到这两个条件中有一个条件不满足,那么我们进行下一步的处理。如果是之前被访问过的,那么就是有重复值,否则就是有新的数加入,我们把该数对应的hashtable置一,numtable里存该数。

值得学习的一点是,通过对数组长度的取余,实现循环对数组遍历。
assign=(assign+1)%length;
因为不断加一以致于超过数组长度后,又会从头开始了。
但是这里的assign<0为什么要做这个判断我不清楚。不加的话又ac不了。

其实这个做法我还是不是很理解,但是基本的思路就是哈希表,即看该数对应的数是多少,看出有没有被访问过。可能再看看哈希表的实现会对这道题的别人的解法理解得透彻一些。以后可以再看看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值