力扣219. 存在重复元素 II

95 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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)

链接:leetcode.cn/problems/co…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

  1. 这道题考察了什么思想?你的思路是什么?

    我的思路很简单,遍历数组nums,如果存在i,j使得 ijk 并且 [j]nums[i]=nums[j],我们就直接return true,否则返回false。

    我们需要使用一个哈希表记录每个元素的最大下标。为什么是记录最大下标呢?因为我们是遍历数组nums,如果不记录当前的最大下标,就会导致后面的和前面的差值绝对值越来越大,比k小的几率就越来越小。

    我们只需要进行以下操作即可

    • 如果哈希表中已存在的和nums[i]相等的元素和哈希表中记录的下标j有i-j小于或等于k的关系,我们就返回true。
    • 将num[i]和下标i存入哈希表,此时i是nums[i]的最大下标。
  2. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    是一次通过的!!!!这道题目太简单了啊!

  3. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

还有第二种解法,就是利用滑动窗口。

image.png

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 之前的元素中寻找与当前元素相等的元素及该元素的最大下标。

模板来源

作者:掘金酱

链接:juejin.cn/post/706970…

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。