2020-04-22
数组中的K-diff数对
给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对。
这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,
且两数之差的绝对值是 k.
题解:
思路1:排序+双指针查找
先从小到大排序 然后逐个比较差值 找出符合要求的 注意重复的情况var findPairs = function (nums, k) { let result = 0; let tmp; // 记录上一次的nums[i] 跟这一次的进行比较 如果相等 直接i++ nums = nums.sort((a, b) => a - b); // 从小到大排序 方便处理重复的情况 for (let i = 0; i < nums.length - 1; i++) { if (tmp === nums[i]) continue; // 如果这次的值跟上一次相等 直接i++ 避免出现重复 for (let j = i + 1; j < nums.length; j++) { if ((nums[j] - nums[i]) === k) { // 如果差值等于k result++; break; // 因为数组已经排序了 只要出现了符合要求的情况 那么接下来的差值肯定是≥k 等于的话那么就是重复的 } else if (nums[j] - nums[i] > k) break; // 如果出现差值大于k 那么直接退出内层循环 因为差值只会越来越大 } tmp = nums[i]; } return result; };
思路2:SET
利用两个数的绝对值之差为 k 的关系 x - y = k,推出 y = x - k 和 x = y + k:
- visit 集合保存访问过的元素
- diff 集合保存已找到的 k-diff 数对中的较小值
- 遍历所有元素,判断当前元素是否符合下面 2 个条件之一
- 如果 y = x - k (1 = 3 - 2) 在 visit 中,则在 diff 中加入较小值 x - k = 1
- 如果 x = y + k (3 = 1 + 2)在 visit 中,则在 diff 中加入较小值 y = 1
- 在 visit 中加入已访问的元素
- 放回 diff 集合的大小(set 相同的元素只存放一次)
var findPairs = function (nums, k) { if (k < 0) return 0; let visit = new Set(), // 存已访问的元素 diff = new Set(); // 存符合要求的diff组合的较小的那一个 for (let n of nums) { // 在已访问的项中存在 n - k, 那么 (n - (n-k)) = k 符合diff数对的要求 其中n - k是较小的那个 存入diff中 if (visit.has(n - k)) diff.add(n - k); // 在已访问的项中存在 n + k,那么 (n + k) - n = k 符合要求 n 是较小的那个 存入diff中 if (visit.has(n + k)) diff.add(n); visit.add(n); // 每次遍历 把本次的项存入已访问的visit中 } return diff.size; // 遍历结束后 diff的长度就是符合要求的对数 }