LeetCode探索(五):219_存在重复元素 II

158 阅读2分钟

这是我参与11月更文挑战的第 12 天,活动详情查看:2021最后一次更文挑战

前言

算法,对于前端er来说是既熟悉又陌生的。 说到熟悉,在我们日常的写bug 🐛 的过程中,我们总会有意无意地用到了算法,比如最简单的数组sort()排序、Math.max()Math.min()等方法。说到陌生,我们很少去深入探索算法是怎么实现的、不同算法之间的优劣、算法的执行效率... =_=

算法对于每个开发者来说都是一门至关重要的必修课。学会算法,不仅有助于我们更好地解决问题,还有助于学习源码、面试等等。不过,前端岗位对于算法的要求不是很高,不需要面面面俱到,我们可以从简单的入门,掌握常用的算法,抓住侧重点即可。

为了学习和巩固常用的算法,这里整理了一个LeetCode算法解题系列,包括解题思路和通用的解法。学习算法没有捷径可走,唯有在不断做题的过程中去总结和掌握!

题目

给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。

示例 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

思考

题目中说到i 和 j 的差的绝对值至多为 k,那么我们可以借助一个大小为k的滑动窗口来解决问题,也就是每次移动时所选择的区间大小都是一致的,设置为k。

同时,考虑到我们会做多次的搜索、插入、删除等操作,为了避免每次操作所耗费的时间,我们可以借用哈希表(散列表)来维护一个大小为k的滑动窗口。这可以大大地提升我们的代码的执行效率!🚀

我们可以遍历数组nums,判断数组元素是否在哈希表中,如果存在则返回true;不存在则添加到哈希表中。同时,为了维护哈希表的大小,每当哈希表的大小超过时,我们要删除哈希表中的第一个元素。这样子,就实现了我们的需求了~

解答

哈希表

/**
 * @author 觅迹
 * @param {number[]} nums
 * @param {number} k
 * @return {boolean}
 */
var containsNearbyDuplicate = function(nums, k) {
  const set = new Set()
  for(let i = 0; i < nums.length; i++) {
    if (set.has(nums[i])) return true // 判断是否在set中
    set.add(nums[i])
    if (set.size > k) {
      set.delete(nums[i - k])
    }
  }
  return false
};

复杂度分析:

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。
  • 空间复杂度:O(min(n, k)),所需的额外空间取决于哈希表中存储的元素的个数。

参考