题目
给你一个整数数组 nums
和一个整数 k
,判断数组中是否存在两个 不同的索引 i
和 j
,满足 nums[i] == nums[j]
且 abs(i - j) <= k
。如果存在,返回 true
;否则,返回 false
。
示例 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
思路:
滑动窗口。借鉴如下思路(未看她代码)
小姐姐刷题-Leetcode 219 Contain duplicate II_哔哩哔哩_bilibili
设置一个set作为窗口,从前往后遍历,如果该值没有在窗口中,就加入,如果加入之后窗口的大小大于k,就踢出去set最开头的那个元素。
代码:
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
set<int> st;
int i = 0;
int len = nums.size();
for(i = 0; i < len; i++){
int tmp = nums[i]; // 存储当前元素
if(st.find(tmp) != st.end()){ // 找到相同的元素了
return true;
break;
} else{
st.insert(tmp); // 将该元素加入窗口(set)中
if(st.size() > k){ // 如果加入之后,窗口大小大于k,即不满足 abs(i-j)<=k
st.erase(nums[i-k]); // 就删掉这个窗口中最开头的元素
}
}
}
// 如果之前没有返回,就说明数组中没有满足条件的值。就返回false
return false;
}
};
知识点
滑动窗口。
注意点:
这里使用set维护窗口的原因是可以自动去重,减少查找消耗。同时有find函数方便查找。
如果使用 vector 维护数组的话,当窗口中很多元素时,查找会超出时间限制。