【LeetCode 217、219、220】存在重复元素、存在重复元素 II、存在重复元素 III

存在重复元素: 

给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

输入: [1,2,3,1]
输出: true
示例 2:

输入: [1,2,3,4]
输出: false
示例 3:

输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

方法1:利用vector特性先进行sort排序,排序后相等元素一定相邻,进行判断;

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        int len = nums.size();
        sort(nums.begin(),nums.end());
        if(nums.empty()) return false;
        for(int i = 0;i < len-1;++i)
        {
            if(nums[i] == nums[i+1])
            {
                return true;
            }
        }
        return false;
    }
};

方法2:利用unordered_set容器,其中有一个find(val)操作,意思是在 unordered_set容器中查找val值,如果找到就返回值所在下标,如果没有找到就返回unordered_set容器末尾元素;在这个过程中不断进行插入元素过程,进行比较;

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_set <int> s;
        for(int i = 0;i < nums.size();++i)
        {
            if(s.find(nums[i]) != s.end()) //如果没有返回末尾元素说明找到相同元素
                return true; 
            s.insert(nums[i]); //不断进行插入操作
        }
        return false;
    }
};

存在重复元素 II:

给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。

示例 1:

输入: nums = [1,2,3,1], k = 3
输出: true
示例 2:

输入: nums = [1,0,1,1], k = 1
输出: true
示例 3:

输入: nums = [1,2,3,1,2,3], k = 2
输出: false

思路:同样利用unordered_set容器进行操作,其中有erase操作,意思是当unordered_set容器值超过k值范围时,就进行删除操作,删除unordered_set中第一个元素,不断进行比较;

class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        unordered_set <int> s;
        for(int i = 0;i < nums.size();++i)
        {
            if(s.find(nums[i]) != s.end())
                return true;
            s.insert(nums[i]);
            if(s.size() > k)
            {
                s.erase(nums[i-k]);
            }
        }
        return false;
    }
};

存在重复元素 III:

给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。

示例 1:

输入: nums = [1,2,3,1], k = 3, t = 0
输出: true
示例 2:

输入: nums = [1,0,1,1], k = 1, t = 2
输出: true
示例 3:

输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false

思路:unordered_set容器和set容器最大的区别在于unordered_set底层是基于哈希表,内部值是无序的,但是set底层由红黑树实现,有自动排序功能,这里选择使用set容器;其中lower_bound(val)操作,是在set容器中first和end中的前闭后开区间进行二分查找,查找大于或等于val的第一个元素下标;如果其中所有元素都小于val,则返回end()的位置;

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        set<long> s;
        long it = t;
        for(int i = 0;i < nums.size();++i)
        {
            if(s.size() > k) //s*容纳k+1个值
            {
                s.erase(nums[i-k-1]);
            }
            set<long>::iterator q = s.lower_bound(nums[i]-it); //查找到的元素下标
            if(q != s.end() && (*q)-nums[i] <= it)  //确认查找到!并对值进行确认
                return true;
            s.insert(nums[i]);
        }
        return false;
    }
};

(∩•̀ω•́)⊃-*⋆代码参考:https://blog.csdn.net/my_clear_mind

上一篇:unordered_map


下一篇:10--STL无序容器(Unordered Containers)