JS查找表和活动窗口

存在重复元素 II

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

示例:

输入: 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
  • 结合使用滑动窗口和查找表,不断查找当前滑动窗口内有没有重复值。我们通过建立一个 record 查找表,表中存的是窗口中的数,另外我们要注意的是,当窗口的大小 > k 的时候,我们要移除 record 中最左边的元素(保证我们窗口中有 <= k 个数)
//执行用时 :68 ms, 在所有 javascript 提交中击败了92.48%的用户
//内存消耗 :39 MB, 在所有 javascript 提交中击败了50.42%的用户
var containsNearbyDuplicate = function (nums, k) {
  let len = nums.length;

  if (len <= 1) return false;
  let count = new Set();
  for (let i = 0; i < len; i++) {
    if (count.has(nums[i])) {
      return true;
    }

    count.add(nums[i]);
    if (count.size > k) {
      count.delete(nums[i - k]);
    }
  }
  return false;
};
  • 对比数组的遍历查找就相对慢很多
//执行用时 :96 ms, 在所有 javascript 提交中击败了47.52%的用户
//内存消耗 :42.6 MB, 在所有 javascript 提交中击败了14.05%的用户
var containsNearbyDuplicate = function (nums, k) {
  let hash = [];
  for (let i = 0, len = nums.length; i < len; i++) {
    if (hash[nums[i]] === undefined) {
      hash[nums[i]] = i;
    } else {
      if ((i - hash[nums[i]]) <= k) return true;
      hash[nums[i]] = i;
    }
  }
  return false;
};


//执行用时 :1604 ms, 在所有 javascript 提交中击败了20.00%的用户
//内存消耗 :38.6 MB, 在所有 javascript 提交中击败了53.72%的用户
var containsNearbyDuplicate = function (nums, k) {
  let len = nums.length;

  if (len <= 1) return false;
  let count = [];
  for (let i = 0; i < len; i++) {
    if (count.includes(nums[i])) {
      return true;
    }

    count.push(nums[i]);
    if (count.length > k) {
      count.shift();
    }
  }
  return false;
};
存在重复元素 III

给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ

示例:

输入: nums = [1,2,3,1], k = 3, t = 0
输出: true

输入: nums = [1,0,1,1], k = 1, t = 2
输出: true

输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false
  • 也是查找表与滑动窗口的思路:维持滑动窗的大小最大为 k,遍历每一个元素 nums[i],在活动窗口中寻找 |one-nums[i]| < t,即窗口中的元素范围为:[one-t … one+t] 之间
//执行用时 :64 ms, 在所有 javascript 提交中击败了94.19%的用户
//内存消耗 :36.2 MB, 在所有 javascript 提交中击败了22.22%的用户
var containsNearbyAlmostDuplicate = function (nums, k, t) {
  let len = nums.length;

  if (len <= 1) return false;
  let count = new Set();
  for (let i = 0; i < len; i++) {
    if (t == 0) {
      if (count.has(nums[i])) {
        return true;
      }
    } else {
      for (let x of count) {
        if (Math.abs(nums[i] - x) <= t) {
          return true;
        }
      }
    }
    count.add(nums[i]);
    if (count.size > k) {
      count.delete(nums[i - k]);
    }
  }
  return false;
};
  • 数组遍历
//执行用时 :260 ms, 在所有 javascript 提交中击败了64.52%的用户
//内存消耗 :35.4 MB, 在所有 javascript 提交中击败了29.63%的用户
var containsNearbyAlmostDuplicate = function (nums, k, t) {
  let len = nums.length;
  if (len <= 1) return false;
  var res = [];
  for (let i = 0; i < len; i++) {
    for (let j = 0; j < res.length; j++) {
      if (Math.abs(res[j] - nums[i]) <= t) { //&& j - i <= k
        return true;
      }
    }

    res.push(nums[i]);
    if (res.length > k) {
      res.shift();
    }
  }
  return false;
};

来源:力扣(LeetCode)https://leetcode-cn.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值