<LeetCode OJ> 217./219. Contains Duplicate (I / II)

文章详细介绍了多种方法用于查找数组中的重复元素,包括使用set、map、排序和哈希法。此外,还提供了一种解决在数组中查找距离小于给定整数k的重复元素的方法,利用哈希map实现。每种方法都进行了时间复杂度分析,旨在优化查找效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.


第一种方法:set数据结构,count函数记录数是否出现过,耗时96ms

用数据结构set来做,因为他是红黑树为底层,所以查找某个元素时间浮渣度较低,并且set不允许相同元素出现
如果某个元素的count为0则,插入到set,如果不为0,return false
set的查找时间为O(lg(N))所以最终时间浮渣度为O(Nlg(N))

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
    if(nums.empty())
        return false;
    set<int> s;
    s.insert(nums[0]);
     for(int i=1;i<nums.size();i++)
     {
         if(!s.count(nums[i]))
             s.insert(nums[i]);
         else
             return true;
     }
     return false;
    }
};


或者set直接查找,100ms:

//思路首先:set查找
class Solution {  
public:  
    bool containsDuplicate(vector<int>& nums) {  
        set<int> st;  
        //for (auto i : nums) {  
        for(int i=0;i<nums.size();i++)
         { 
              if (st.find(nums[i]) != st.end()) 
                    return true;  
              st.insert(nums[i]);  
         }
        return false;  
    }  
};  

第二种方法:map数据结构,count函数记录数是否出现过,96ms

//思路首先:
//既然可以用set来做,那么map来做也是可以的
//因为map不允许关键值重复(但实值可以),道理和set一样,都是红黑树为底层,本方法96ms完成测试案例
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        if(nums.empty())
            return false;
        map<int, int> mapping;
        for (int i = 0; i<nums.size(); i++) {
            if(mapping.count(nums[i]))//如果该数出现过
                return true;
            mapping.insert(pair<int, int>(nums[i], i));//将nums[i]存储为关键值,实值在这里无所谓    
        }
        return false;
    }
};


或者map直接查找,100ms:

//思路首先:map查找
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        if(nums.empty())
            return false;
        map<int, int> mapping;
        for (int i = 0; i<nums.size(); i++) {
            if(mapping.find(nums[i]) != mapping.end())//查找该数是否出现过
                return true;
            mapping.insert(pair<int, int>(nums[i], i));//将nums[i]存储为关键值,实值在这里无所谓    
        }
        return false;
    }
};


第三种方法:先排序,再遍历一遍,检查数是否出现过,40ms

//思路首先:先排序,再遍历一遍是否有相同值,所以最终时间浮渣度为O(Nlg(N)+N),本方法40ms完成测试案例
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
    if(nums.empty())
        return false;
    sort(nums.begin(), nums.end());
    for (int i = 1; i < nums.size(); i++) {
        if (nums[i-1] == nums[i]) 
            return true;
    }
    return false;
    }
};


第四种方法:哈希法,检查数是否出现过,48ms

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





有一个数组和一个整数,判断数组中是否存在两个相同的元素相距小于给定整数k。若是则返回真。

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between i and jis at most k.


分析:

哈希map(不要用红黑树map)
遍历数组,首先看当前元素是否在map中,如不在则压入,若在看是否其对应下标和当前下标相距为k
如果不则将原元素修改为现在的下标

class Solution {  
public:  
    bool containsNearbyDuplicate(vector<int>& nums, int k) {  
        if(nums.empty())  
            return false;  
        unordered_map<int,int> umapping;  
        umapping[nums[0]]=0;  
        for(int i=1;i<nums.size();i++)  
        {  
            //if(umapping.count(nums[i]) == 0)//没有出现(统计函数)  
            if(umapping.find(nums[i]) == umapping.end())//直接查找  
                umapping[nums[i]]=i;  
            else if((i-umapping[nums[i]])<=k)//相距小于k  
                return true;  
            else  
                umapping[nums[i]]=i;  
        }  
        return false;  
    }  
};  



注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.youkuaiyun.com/ebowtang/article/details/50443891

原作者博客:http://blog.youkuaiyun.com/ebowtang

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值