题目
给你一个整数数组 nums 和两个整数 indexDiff 和 valueDiff 。
找出满足下述条件的下标对 (i, j):
i != j
abs(i - j) <= indexDiff
abs(nums[i] - nums[j]) <= valueDiff
如果存在,返回 true ;否则,返回 false 。
输入:nums = [1,5,9,1,5,9], indexDiff = 2, valueDiff = 3 输出:false
题解
第一种
我们在函数中使用了两个循环,外层循环遍历nums数组中的每一个元素,内层循环则在当前元素的左右k个元素中查找与当前元素的差的绝对值不超过t的元素,我们先声明了一个变量num,用于记录符合条件的元素对的数量,默认值为0,然后我们对于每个元素m,找到它左右k个元素组成的子数组set,并遍历这个子数组set中的每个元素v,如果当前元素m和子数组set中的某个元素v之差的绝对值不超过t,那么我们就将num加1,如果此时num等于2则说明找到了两个符合条件的元素,我们直接返回true即可,如果内层循环结束后仍然没有找到符合条件的元素对,我们则将num重置为0,外层循环结束后如果仍然没有找到符合条件的元素,我们则返回false即可
var containsNearbyAlmostDuplicate = function(nums, k, t) { let num = 0; for (let i = 0; i < nums.length; i++) { const m = nums[i]; const left = i - k < 0 ? 0 : i - k; const right = i + k + 1; const set = nums.slice(left,right); for (const v of set) { if (Math.abs(v - m) <= t){ num++; if (num === 2) return true; }; } num = 0; } return false; };
第二种
我们在函数中使用了一个Map数据结构mp来存储元素的信息,我们先进行遍历数组nums中的每个元素,对于每个元素x,我们根据给定的参数t计算出一个id值,用于我们将元素分组,如果mp中已经存在相同的id值则说明存在一个索引之差不超过k的元素对,我们直接返回true,如果mp中不存在相同的id值,我们继续检查相邻的两个分组,就是id-1和id+1对应的分组,如果mp中存在id-1对应的分组并且元素x与该分组中的元素的值之差的绝对值不超过t,我们则返回true,如果mp中存在id+1对应的分组并且元素x与该分组中的元素的值之差的绝对值不超过t,我们同样返回true,如果上述条件都不满足,则说明当前元素x与之前的元素都不满足,我们就将当前元素x添加到mp中,如果mp的大小超过了k,我们就删除最旧的那个元素,保证mp中只存储最近的k个元素的信息,当我们遍历完整个数组nums后都没有返回true,那么我们直接返回false即可
var containsNearbyAlmostDuplicate = function(nums, k, t) { const n = nums.length; const mp = new Map(); for (let i = 0; i < n; ++i) { const x = nums[i]; const id = getID(x, t + 1); if (mp.has(id)) { return true; } if (mp.has(id - 1) && Math.abs(x - mp.get(id - 1)) <= t) { return true; } if (mp.has(id + 1) && Math.abs(x - mp.get(id + 1)) <= t) { return true; } mp.set(id, x); if (i >= k) { mp.delete(getID(nums[i - k], t + 1)); } } return false; }; const getID = (x, w) => { return x < 0 ? Math.floor((x + 1) / w) - 1 : Math.floor(x / w); }