目录
一、217. 存在重复元素
用哈希表解决
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> table;
for(auto n:nums){
if(table.contains(n))
return true;
table.insert(n);
}
return false;
}
};
排序后,相等的元素必然相邻
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
sort(nums.begin(),nums.end());
int len = nums.size();
for(int i = 1;i <len;i++){
if(nums[i] == nums[i-1])
return true;
}
return false;
}
};
二、219. 存在重复元素 II
用哈希表解决
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_map<int,int> num2Idx;
int len = nums.size();
for(int i = 0;i <len;i++){
if(num2Idx.contains(nums[i]) && i - num2Idx[nums[i]] <=k)
return true;
num2Idx[nums[i]] = i;
}
return false;
}
};
用滑动窗口+哈希表解决。假如当前遍历到了第i个元素,哈希表维护【i-k,i-1】这个长度为k的滑动窗口范围内的元素。
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_set<int> table;
int len = nums.size();
for(int i = 0;i < len;i++){
if(i>k)
table.erase(nums[i-k-1]);
if(table.contains(nums[i]))
return true;
table.insert(nums[i]);
}
return false;
}
};
三、220. 存在重复元素 III
这道题相比于第219题更进一步。需要在长度最大为indexDiff的滑动窗口内的元素中寻找离当前数最近的那个数。可以对滑动窗口内的元素排序,然后二分查找,如果每次都生成新的滑动窗口序列并排序然后再查找会超时。可以使用有序集合std::set,支持插入新的元素和移除前面被滑出去的元素。
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int indexDiff, int valueDiff) {
int len = nums.size();
set<int> window;
for(int i = 0;i < len;i++){
if(i > indexDiff)
window.erase(nums[i-indexDiff-1]);
auto iter = window.lower_bound(nums[i]);
if(iter == window.end()){
if(window.size()!=0 && ((nums[i] - *(--iter)) <= valueDiff))
return true;
}else{
if(*iter - nums[i] <= valueDiff)
return true;
if(iter!=window.begin() && ((nums[i] - *(--iter)) <= valueDiff))
return true;
}
window.insert(nums[i]);
}
return false;
}
};