携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
题目(Contains Duplicate III)
链接:https://leetcode-cn.com/problems/contains-duplicate-iii
解决数:567
通过率:29.1%
标签:数组 桶排序 有序集合 排序 滑动窗口
相关公司:google amazon bytedance
给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k **。
如果存在则返回 true,不存在返回 false。
示例 1:
输入: nums = [1,2,3,1], k = 3, t = 0
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1, t = 2
输出: true
示例 3:
输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false
提示:
0 <= nums.length <= 2 * 104-231 <= nums[i] <= 231 - 10 <= k <= 1040 <= t <= 231 - 1
思路
请看代码
代码
/**
* @param {number[]} nums
* @param {number} k
* @param {number} t
* @return {boolean}
*/
var containsNearbyAlmostDuplicate = function (nums, k, t) {
function getId(x) {
return Math.floor(x / (t + 1));
}
if (t < 0) return false;
// 大桶,里面最多有k个小桶。(超过k的时候会删除第一个小桶,滑动窗口的概念
const map = new Map();
for (let i = 0; i < nums.length; i++) {
// m是当前遍历元素将要在的桶
const m = getId(nums[i]);
// 当前大桶中有这个小桶的话,说明存在重复且符合条件,下面两个条件也一样。每次会对比桶的左右小桶。
if (map.has(m)) {
return true;
// 如果当前小桶的右边桶存在,且两个桶相差小于t
} else if (map.has(m + 1) && Math.abs(map.get(m + 1) - nums[i]) <= t) {
return true;
// 如果当前小桶的左边桶存在,且两个桶相差小于t
} else if (map.has(m - 1) && Math.abs(map.get(m - 1) - nums[i]) <= t) {
return true;
}
// 将这个桶存到大桶里面
map.set(m, nums[i]);
// 如果i大于k,也就是大桶装满了,则需要把大桶里面的第一个小桶删了。
if (i >= k) {
map.delete(getId(nums[i - k]));
}
}
return false;
};
- 一直在纠结-0 === 0 为true这个问题,最后觉得只要向下取整其实也可以解决这个问题
- 不一定用map,用最简单的对象当然也行
/**
* @param {number[]} nums
* @param {number} k
* @param {number} t
* @return {boolean}
*/
var containsNearbyAlmostDuplicate = function(nums, k, t) {
// 解决js中 -0 === 0 为true的问题
function getId(x, w) {
return Math.floor(x / w)
}
if (t < 0) return false
const map = new Map()
const w = t + 1
for (let i = 0; i < nums.length; i++) {
const m = getId(nums[i] ,w)
if (map.has(m)) return true
else if (map.has(+m + 1) && Math.abs(map.get(+m + 1) - nums[i]) < w) return true
else if (map.has(+m - 1) && Math.abs(map.get(+m - 1) - nums[i]) < w) return true
map.set(m, nums[i])
if (i >= k) map.delete(getId(nums[i - k], w))
}
return false
};