算法题解- 存在重复元素

165 阅读3分钟

题目

给你一个整数数组 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);
}

坚持努力,无惧未来!