开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详情
LeetCode 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)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
这道题目我的思路是这样,就是建立一个map集合,然后遍历整数数组,将得到的值进行判断。如果该值不存在于切片中,我们就将该值放入切片中。如果该值在切片之中,我们就用此时的索引减去切片中的值,然后与k进行比较,如果大于k,就将当前的索引覆盖到当前值对应的v(键值对的v)中。如果小于或等于k,直接返回true,如果遍历完成仍未返回true,我们就返回false。
经实现和提交代码,此思路是可行的,代码如下AC代码栏目可见。
-
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
不是一次通过的,刚开始没有写如果map中没有找到值的情况。
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 } -
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
维护一个长度为k+1的集合作为窗口,判断是否出现重复,元素个数满了的话弹出k+1个前的数字。
func containsNearbyDuplicate(nums []int, k int) bool { set := map[int]bool{} for i := 0; i < len(nums); i++ { if len(set) == k + 1 { delete(set, nums[i - k - 1]) } if set[nums[i]] { return true } set[nums[i]] = true } return false } 作者:himymBen 链接:https://leetcode.cn/problems/contains-duplicate-ii/solution/pythonjavajavascriptgo-hua-dong-chuang-k-px1z/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三、AC 代码:
func containsNearbyDuplicate(nums []int, k int) bool { n_map := make(map[int]int) for i,v := range nums{ if _,ok := n_map[v];ok{ if i - n_map[v] > k{ n_map[v] = i }else { return true } }else { n_map[v] = i } } return false }执行结果:
通过
执行用时:88 ms, 在所有 Go 提交中击败了89.85%的用户
内存消耗:11.4 MB, 在所有 Go 提交中击败了31.08%的用户
通过测试用例:54 / 54
四、总结:
这道题目总体上耗时比较简单的,使用滑动窗口和哈希表的区别就是滑动窗口的空间复杂度比较低,与判断重复元素时允许的下标差的绝对值的最大值有关。
模板来源
作者:掘金酱
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。