mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
Create 220. Contains Duplicate III.md
This commit is contained in:
parent
26053250a9
commit
99585d49dc
56
solutions/220. Contains Duplicate III.md
Normal file
56
solutions/220. Contains Duplicate III.md
Normal file
@ -0,0 +1,56 @@
|
||||
# [220. Contains Duplicate III](https://leetcode.com/problems/contains-duplicate-iii/)
|
||||
|
||||
# 思路
|
||||
给定一个数组. 判断是否满足: 存在两个元素,两个元素的下标差的绝对值不能大于k,值差的绝对值不能大于t。
|
||||
|
||||
基本思路很好想: 用一个大小为k起始下标为i+1的滑窗,
|
||||
判断滑窗内是否存某个元素使nums[i]与此元素之差的绝对值不大于t(即找到滑窗内与nums[i]最接近的那个元素判断二者之差的绝对值是否不大于t).
|
||||
|
||||
如果我们暴力地遍历一遍滑窗内元素来判断"是否存某个元素使nums[i]与此元素之差的绝对值不大于t"的话每次判断复杂度为O(k),
|
||||
但是如果我们始终将滑窗内的元素维护成有序的话查找复杂度就为log(k)了, 而平衡二叉树(或其改进版)红黑树)的插入,删除,查找的复杂度都是logN级别, 满足我们需要.
|
||||
而在STL中, 内部实现为红黑树的容器有set和map(其实还有multimap和multiset).
|
||||
|
||||
另外为了找到与nums[i]最接近的x使`|nums[i]-x| <= t`, 即`nums[i]-x <= t`且`nums[i]-x >= -t`, 即`nums[i]-t <= x`且`x-nums[i] <= t`,
|
||||
我们可以先用二分法lower_bound找到满足`nums[i]-t <= x`的x, 再判断是否满足`x-nums[i] <= t`即可.
|
||||
|
||||
* 注意map和set在插入时写法不同, 另外根据迭代器访问值的写法也不一样.
|
||||
* 灵活运用lower_bound和upper_bound.
|
||||
|
||||
# C++
|
||||
## 用map
|
||||
``` C++
|
||||
class Solution {
|
||||
public:
|
||||
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
|
||||
map<long long, int> window; // 用long long是为了防止溢出
|
||||
|
||||
for(int i = 0; i < nums.size(); i++){
|
||||
if(i > k) window.erase(nums[i - k - 1]); // 保持k个值
|
||||
auto x = window.lower_bound((long long)nums[i] - t);
|
||||
if(x != window.end() && (x -> first - nums[i]) <= t)
|
||||
return true;
|
||||
window[nums[i]] = i; // 等于任意值都可以
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 用set
|
||||
``` C++
|
||||
class Solution {
|
||||
public:
|
||||
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
|
||||
set<long long> window;
|
||||
|
||||
for(int i = 0; i < nums.size(); i++){
|
||||
if(i > k) window.erase(nums[i - k - 1]); // 去除掉窗口范围外的值
|
||||
auto x = window.lower_bound((long long)nums[i] - t);
|
||||
if(x != window.end() && (*x - nums[i]) <= t) // 注意写法
|
||||
return true;
|
||||
window.insert(nums[i]); // 注意写法
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
```
|
Loading…
Reference in New Issue
Block a user