面试经典150题[046]:存在重复元素 II(LeetCode 219)
存在重复元素 II(LeetCode 219)
题目链接:存在重复元素 II(LeetCode 219)
难度:简单
1. 题目描述
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
要求:
- 1 <= nums.length <= 10^5
- -10^9 <= nums[i] <= 10^9
- 0 <= k <= 10^5
示例:
输入: nums = [1,2,3,1], k = 3
输出: true
输入: nums = [1,0,1,1], k = 1
输出: true
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
2. 问题分析
2.1 规律
- 数组中需要检测是否存在距离不超过 k 的重复元素。
- 暴力遍历每对元素会达到 O(n^2) 时间复杂度,鉴于 n <= 10^5,会超时。
- 核心问题:如何高效追踪最近出现的重复元素,并检查其距离是否 <= k?
2.2 哈希表思路
我们使用哈希表(字典)记录每个元素最近出现的索引:
- 遍历数组,对于每个 nums[i]:
- 如果 nums[i] 已存在于哈希表中,且当前索引 i 与其最近索引的差值 <= k,则返回 true。
- 否则,更新哈希表中 nums[i] 的索引为 i。
- 此方法只记录最近索引,确保检测到最接近的重复对,同时满足距离要求。
- 备选:使用大小为 k 的滑动窗口 + 集合,添加元素前检查是否存在,超出窗口时移除最早元素。空间可优化为 O(k)。
3. 代码实现
Python
class Solution:def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:index_map = {}for i, num in enumerate(nums):if num in index_map and i - index_map[num] <= k:return Trueindex_map[num] = ireturn False
C++
class Solution {
public:bool containsNearbyDuplicate(vector<int>& nums, int k) {unordered_map<int, int> index_map;for (int i = 0; i < nums.size(); ++i) {if (index_map.count(nums[i]) && i - index_map[nums[i]] <= k) {return true;}index_map[nums[i]] = i;}return false;}
};
4. 复杂度分析
- 时间复杂度:O(n),遍历一次数组,每次哈希操作平均 O(1)。
- 空间复杂度:O(n),最坏情况下存储所有独特元素。
5. 总结
- 重复元素 + 距离限制 → 哈希表记录最近索引是高效选择。
- 可扩展到滑动窗口变体,适用于 k 较小时优化空间。
- 类似问题如寻找无重复子串,但这里焦点在固定距离内重复。
复习
面试经典150题[016]:接雨水(LeetCode 42)
面试经典150题[031]:最长无重复字符子串(LeetCode 3)