题目:219.存在重复元素 II
给你一个整数数组 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
- 提示:
1 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
0 <= k <= 10^5
思路1
- 创建一个哈希表,用于记录每个元素的最新索引。
- 遍历数组,对于每个元素:
- 如果该元素已经在哈希表中存在,并且当前索引与记录的索引之间的距离小于等于
k,则返回true。 - 更新该元素在哈希表中的最新索引。
- 如果该元素已经在哈希表中存在,并且当前索引与记录的索引之间的距离小于等于
- 如果遍历完数组没有找到满足条件的元素,返回
false。
- 时间复杂度:O(n)
- 空间复杂度:O(n)
代码
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer, Integer> numIndex = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 检查哈希表中是否存在相同元素,并且索引距离小于等于 k
if (numIndex.containsKey(nums[i]) && i - numIndex.get(nums[i]) <= k) {
return true;
}
numIndex.put(nums[i], i);
}
return false;
}
思路2
- 使用一个哈希表来存储当前窗口内的元素及其索引。
- 使用一个固定大小为
k的滑动窗口来遍历数组。 - 在遍历过程中,将当前元素加入滑动窗口,如果滑动窗口的大小超过
k,则移除滑动窗口最左侧的元素。 - 检查当前元素是否已经在滑动窗口中存在,如果存在则返回
true,否则继续。
- 时间复杂度:O()
- 空间复杂度:O()
代码
public boolean containsNearbyDuplicate(int[] nums, int k) {
// 创建一个哈希表来记录当前窗口内的元素及其索引
Map<Integer, Integer> numIndex = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 检查当前元素是否已经在滑动窗口内
if (numIndex.containsKey(nums[i])) {
return true;
}
numIndex.put(nums[i], i);
// 如果滑动窗口的大小超过 k,则移除最左侧的元素
if (numIndex.size() > k) {
numIndex.remove(nums[i - k]);
}
}
return false;
}