题目描述
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值不超过 k。
示例
输入: nums = [1,0,1,1], k = 1
输出: true
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
解题思路
暴力解法
本题还有个简单版的存在重复元素,题目是从一个数组nums中查询是否存在重复元素,可直接用Set的特性进行求解,较为简单。但本题需要两个元素间的距离不超过k,故本题第一思路即是进行循环遍历所有元素进行求解,代码如下:
public boolean containsNearbyDuplicate(int[] nums, int k) {
for(int i=0;i<nums.length;i++){
int index = (nums.length-i>k) ? k+i+1 : nums.length;
for(int j=i+1;j<index;j++){
if(nums[i] == nums[j]){
return true;
}
}
}
return false;
}
优化
但是上述方法的时间复杂度较高,为,显然是需要优化的,查看LeetCode评论中大神的分析,还是与简单版的该题思路一样使用Set的特性去重,如果set中元素超过k个,则将首元素删掉,因为hashset的add方法时间复杂度为,故该算法时间复杂度降低为,通过思路编写代码如下:
public boolean containsNearbyDuplicate(int[] nums, int k) {
Set<Integer> set = new HashSet<>();
for(int i=0;i<nums.length;i++){
if(i<=k){
set.add(nums[i]);
if(set.size() != i+1){
return true;
}
}else {
set.remove(nums[i-k-1]);
set.add(nums[i]);
if(set.size() != k+1){
return true;
}
}
}
return false;
}
由于笔者水平有限,代码可读性较差,通过对比大神们的代码,优化了代码的结构,提高了可读性,优化后代码如下:
public boolean containsNearbyDuplicate(int[] nums, int k) {
HashSet<Integer> set = new HashSet<>();
for(int i = 0; i < nums.length; i++) {
if(set.contains(nums[i])) {
return true;
}
set.add(nums[i]);
if(set.size() > k) {
set.remove(nums[i - k]);
}
}
return false;
}