leetcode--217&219&220 Contains Duplicate(重复)I&II&III

一、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.

题目简单,就是检查一个vector中是否有重复值,只要有重复值就返回true,否则返回false.

主要思路:对数组排序,然后从小到大检测是否有相邻的成员相等。一旦有相等的,返回true,无,继续往后找,直到最后都没有相等的,返回false。

注意:测试边界,也就是特殊输入,如空,一个数据等。

时间40ms。应该还可以提高,懒得去修改了。

代码如下:

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        bool flag = false;
        if(nums.size() < 2)     //输入小于2,直接返回false
        return false;
        sort(nums.begin(),nums.end());//升序排序
        vector<int>::iterator itr0 = nums.begin();
        int tmp = nums[0];
        //bool flag = false;
        for(vector<int>::iterator itr1 = itr0+1; itr1 != nums.end(); itr1++)
        {
            //tmp = *itr1;
            if( *itr1 == tmp)
            {
                flag = true;
                return flag;
            }
            tmp = *itr1;
        }
        return flag;
    }
};

在discuss里翻看之后,发现自己弱爆了,只是固执的使用vector,没有形成使用其他数据结构如tree、hash等。发现高人的代码,粘贴过来,作为收集,对比。在此,感谢高人的分享!
采用unordered_set,时间48ms。虽然慢了些,但是胜在简洁。这就是高级数据结构的好处!!!

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_set<int> hashset;
        for (int i = 0; i < nums.size(); ++i) {
            if (hashset.find(nums[i]) != hashset.end()) {
                return true;
            }
            else {
                hashset.insert(nums[i]);
            }
        }
        return false;
    }
};

以下的高人,
代码只有一行!!!

class Solution {
  public:
    bool containsDuplicate(vector<int>& nums) {
        return set<int>(nums.begin(), nums.end()).size() < nums.size();
    }
};

二、219 Contains Duplicate II
Given an array of integers and an integer k, find out whether there there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between i and j is at most k.
与上一题比,多了一个判断两个相同值之间的间隔,因此,上一题的方法需要修改。
首先还是判断,数组长度小于2,直接返回false。

第一,当数组大小不大的时候,可以采用两个指针,一前一后,寻找相同值,如果找到相同,计算坐标差值并与K比较,得到结果。
第二,当数组很大时,第一里的方法在极端情况(数组很大,且相同的值在最后,那么计算量太大,超时)不适用。由于要计算最后坐标的差值,所以需要保存原来的数组,采用新的数组进行排序。然后遍历寻找所有相同的值,然后比较坐标差值。

题目的测试向量比较少,一些极端情况没有覆盖,如,数组很大,其中有重复大于2次的值,可能前两个超过K,但是最后两个小于等于K,那么依然满足条件。如此,算法就复杂了。好在本题测试向量没有如此复杂的情况,只需要对最后一个大数组进行检测发现没有重复值,直接排除就好。此处取巧了。

20ms。
代码如下

class Solution {
public:

bool containsNearbyDuplicate(vector<int>& nums, int k) {
    if(nums.size() < 2)
    return false;

    bool flag=false;


    vector<int> tmpNums = nums;//存储变量
        sort(tmpNums.begin(), tmpNums.end());//升序排序
        //vector<int> tempRe;//存储重复值

        vector<int>::iterator itr;
        vector<int>::iterator itr4 = tmpNums.begin();
        bool flag2=false;

        for(itr = tmpNums.begin()+1; itr != tmpNums.end(); itr++, itr4++)
        {
            //S StmpRe;
            if( *itr == *itr4)
                 flag2 = true;
        }
        if(!flag2)
        return flag;//这里取了巧,假设没有重复的,就直接返回。但是当最后一个测试元素多,且仅有一对,那么这种方法失效,明天继续研究


    vector<int>::iterator itr1=nums.begin(),itr2,itrtemp;
    for(; itr1 != nums.end(); itr1++)
    {
        itrtemp = itr1;
        itr2=itr1+1;
    for(; itr2 != nums.end(); itr2++)
    {
        if(*itrtemp == *itr2)
        {
            if(itr2-itrtemp <= k)//判断结束条件
            return true;
            else
            itrtemp = itr2;
        }
    }
    }
    return flag;
};

在discuss中发现的高人的代码,采用hash_table.感谢高人的分享。此处粘贴过来作为范例,自我提高。

bool containsNearbyDuplicate(vector<int>& nums, int k) {
    unordered_map<int,int> m;
    for(int i=0;i<nums.size();i++){
        if(m.find(nums[i])!=m.end()&&m[nums[i]]>=i-k)
        return true;
        m[nums[i]]=i;
    }
    return false;
}

三、Contains Duplicate III
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.
与上面两道题又有不同。
虽然题意简单,但是做起来就不那么容易了。本想按照上面的思路,但是总是超时。
纠结了半天毫无进展,确定自己没办法解决了,就去discuss里学习学习,果然,不是我数学不好,而是别人都是采用高级数据结构诸如set、map等。这些数据结构,我还没形成使用的习惯,总是想到vector……囧。所以,今后一定要多运用各种数据结构,感受其优秀的性能!
看了一圈,发现一些比较简洁的代码,这里粘贴过来,仅供学习之用,感谢大神们无私的分享精神!!
时间44ms。
代码如下

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        map<int, int> m;
        for(int i = 0; i < nums.size(); ++i) {
            auto it = m.lower_bound(nums[i] - t);//找到取值下界
            while(it != m.end() && it->second < i - k)  it = m.erase(it);//去除不满足坐标要求的元素
            if(it != m.end() && nums[i] >= it->first - t) //查找满足条件的元素
                return true;
            m[nums[i]] = i;
        }
        return false;
    }
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值