开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情
力扣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
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
我的思路很简单,遍历数组nums,如果存在i,j使得 i−j≤k 并且 [j]nums[i]=nums[j],我们就直接return true,否则返回false。
我们需要使用一个哈希表记录每个元素的最大下标。为什么是记录最大下标呢?因为我们是遍历数组nums,如果不记录当前的最大下标,就会导致后面的和前面的差值绝对值越来越大,比k小的几率就越来越小。
我们只需要进行以下操作即可
- 如果哈希表中已存在的和nums[i]相等的元素和哈希表中记录的下标j有i-j小于或等于k的关系,我们就返回true。
- 将num[i]和下标i存入哈希表,此时i是nums[i]的最大下标。
-
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
是一次通过的!!!!这道题目太简单了啊!
-
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
还有第二种解法,就是利用滑动窗口。
func containsNearbyDuplicate(nums []int, k int) bool {
set := map[int]struct{}{}
for i, num := range nums {
if i > k {
delete(set, nums[i-k-1])
}
if _, ok := set[num]; ok {
return true
}
set[num] = struct{}{}
}
return false
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/contains-duplicate-ii/solution/cun-zai-zhong-fu-yuan-su-ii-by-leetcode-kluvk/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三、AC 代码:
func containsNearbyDuplicate(nums []int, k int) bool {
pos := map[int]int{}
for i, num := range nums {
if p, ok := pos[num]; ok && i-p <= k {
return true
}
pos[num] = i
}
return false
}
四、总结:
两种方法的时间复杂度都为O(n),但是AC代码的时间复杂度为O(n),滑动窗口的空间复杂度为O(k),其中 k是判断重复元素时允许的下标差的绝对值的最大值。
我的方法的两步操作顺序不可以更改,因为当遍历到下标 i 时,只能在下标 i 之前的元素中寻找与当前元素相等的元素及该元素的最大下标。
模板来源
作者:掘金酱
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。