力扣打卡 2022/1/19
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
java代码如下:
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
//题目可以转换成大小为k的滑动窗口中,有无相同大小的数字
HashMap<Integer,Integer>map = new HashMap<>();
for(int i=0;i<nums.length;i++){
if(i>=k+1)
map.remove(nums[i-k-1]);
if(map.put(nums[i],i) != null)
return true;
}
return false;
}
}
思路:题目可以转换成大小为k+1的一个滑动窗口,寻求滑动窗口中是否有值相同。
程序流程:用一个哈希表来存放
- 键值key为nums数组中的变量
- 值value为nums数组的下标
用一个for循环来遍历整个数组,加上分支语句来区别对待:
- 起始阶段:滑动窗口大小不足k+1时。
- 之后阶段:滑动窗口大小为k+1时。
用HashMap中的put函数会返回上一个值value,value为空null,则这个数字在滑动窗口中还未出现过。
利用这一点简化了代码。
给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。如果存在则返回 true,不存在返回 false。
class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
//解题思路:使用TreeSet集合,来实现有序记录数组
TreeSet<Long> set = new TreeSet<>(); //创建一个TreeSet数组,用来记录滑动窗口中所有的元素
for(int i=0;i<nums.length;i++){
Long ceiling = set.ceiling((long)(nums[i])-(long)t); //ceiling函数实现了查找TreeSet中比参数nums[i]-t大的所有元素中最小的那个值是多少
if(ceiling != null && ceiling <= (long)nums[i] + (long)t ){
return true;
}
set.add((long)nums[i]);
if(set.size()>=k+1){ //集合中的元素数量已经大于k了,要删除第一个
set.remove((long)nums[i-k]);
}
}
return false;
}
思路:
- 主要用了TreeSet里,ceiling函数实现了查找TreeSet中比参数nums[i]-t大的所有元素中最小的那个值是多少。
- 这样就查找了滑动窗口中有没有数字在以滑动窗口末尾nums[i]作为中心,区间为[nums-t, nums+t]的这个区间内。