diff --git a/solutions/219. Contains Duplicate II.md b/solutions/219. Contains Duplicate II.md index c6a4685..f2a8bcd 100644 --- a/solutions/219. Contains Duplicate II.md +++ b/solutions/219. Contains Duplicate II.md @@ -1,30 +1,47 @@ # [219. Contains Duplicate II](https://leetcode.com/problems/contains-duplicate-ii/description/) # 思路 -判断数组是否有重复元素,而且重复元素下标差的绝对值不大于k,首先简单的思路就是用map,这里给出另一种解法: -定义一个结构体num_with_index记录数组元素的值和下标,然后再对结构体按照值进行排序,排序后重复元素肯定相邻,再判断下标是否满足条件即可。 +判断数组是否有重复元素,而且重复元素下标差的绝对值不大于k。 + +## 思路一 +为了记录元素到下标的映射,我们可以使用hashmap,key即元素值,value即该元素的下标,这样就很方便的判断某元素是否出现过且下标差是否不大于k。 + +hashmap的为常数时间复杂度,所以总的时间复杂度为O(n) + +## 思路二 +还也可以用pair记录数组元素的值和下标,然后再对所有pair按照元素值的大小进行排序,排序后重复元素肯定相邻,再判断下标是否满足条件即可。 + +由于要排序,所以时间复杂度为O(nlogn) + # C++ + +## 思路一 ``` C++ class Solution { - struct num_with_index{ - int num; - int index; - }; public: - // 这里必须加static否则编译不过,原因参考https://www.cnblogs.com/scoyer/p/6533685.html - static bool mycompare(const num_with_index &a, const num_with_index &b){ - return a.num > b.num; - } bool containsNearbyDuplicate(vector& nums, int k) { - vectornewnums; - num_with_index newnum; + unordered_mapmp; for(int i = 0; i < nums.size(); i++){ - newnum.num = nums[i]; - newnum.index = i; - newnums.push_back(newnum); + auto iter = mp.find(nums[i]); + if(iter != mp.end() && i - iter -> second <= k) return true; + mp[nums[i]] = i; } - sort(newnums.begin(), newnums.end(), mycompare); - for(int i = 1; i < nums.size(); i++) - if(newnums[i].num == newnums[i-1].num && abs(newnums[i].index - newnums[i-1].index) <= k) return true; + return false; + } +}; +``` + +## 思路二 +``` C++ +class Solution { +public: + bool containsNearbyDuplicate(vector& nums, int k) { + vector>num_is; + for(int i = 0; i < nums.size(); i++) num_is.push_back({nums[i], i}); + + sort(num_is.begin(), num_is.end()); // 默认会按照pair的第一个值进行排序 + for(int i = 1; i < nums.size(); i++) + if(num_is[i].first == num_is[i-1].first && + abs(num_is[i].second - num_is[i-1].second) <= k) return true; return false; } };