Contains Duplicate,Contains Duplicate II,Contains Duplicate III

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Contains Duplicate,Contains Duplicate II,Contains Duplicate 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.

判断数组是是否含有重复元素。

思路比较多,暴力查找每个元素、排序后查找、map统计每个元素出现的次数、set不包含重复元素。

有个小技巧,set可以用于去除数组中的重复元素,并且还有排序功能。map可以统计每个元素出现的次数,也有排序功能

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

与上一题类似,不过本题每次查找重复元素的数据范围变为k,也就是希望我们自行维护一个大小为k的滑动窗口。

关于滑动窗口的表示,可以把窗口内的数据装入一个容器内(set,map,vector等),也可以用下标维护一个范围表示,不同的题目灵活选择

关于set/unordered_set中insert的返回值,其返回pair<set/uset迭代器,bool>,第二布尔值为true表示成功插入,为false表示已有该元素,具体可查看cpp reference

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

220. 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.

这题的解题框架还是滑动窗口,不过,并不是判断窗口内是否有重复元素,而是判断窗口内两数的差值关系。如果直接用暴力求得窗口内两数的差值是否小于等于t,需要o(k*k)的时间复杂度,一共有n-k个窗口,如果按照这个思路写代码,会超时。所以另寻出路。暴力其实是没目的的枚举所有数对,而现在我们知道,需要窗口内的两数满足 |a-x|<=t的关系,也就是 a-t =< x <= a+t,所以我们可以用查找的思路,每次往窗口丢入一个数据的时候,检查是否有[a-t,a+t]这个范围内的数据在窗口中。 

假设使用set存储窗口中的数据,那么使用lower_bound函数就可以在o(lgk)时间内找到第一个大于等于a-t的这个数据,再检查一下找到的数据是否小于等于a+t即可

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        
        set<int> windows;
                
        for(int i=0;i<nums.size();++i){
            
            if(i>k){
                windows.erase(nums[i-k-1]);
            }
            
            auto iter = windows.lower_bound(nums[i]-t);
            
            if(iter != windows.end() && *iter <= nums[i] + t){
                return true;
            }
            
            windows.insert(nums[i]);
        }
        return false;
    }
};

 

这三个题的关键词是,滑动窗口,窗口内的数据间的关系

以上是关于Contains Duplicate,Contains Duplicate II,Contains Duplicate III的主要内容,如果未能解决你的问题,请参考以下文章

Contains Duplicate,Contains Duplicate II,Contains Duplicate III

Contains Duplicate

LeetCode Contains Duplicate

219. Contains Duplicate II

LeetCode-Contains Duplicate

217 Contains Duplicate