刷题的日常 - 数组中的 k-diff 数对

118 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

刷题的日常

数组中的 k-diff 数对

来自leetcode每日一题,第532题

题目理解

给定一个整数数组和一个整数k,你需要在数组里找到 不同的k-diff 数对,并返回不同的 k-diff 数对 的数目。
这里将k-diff数对定义为一个整数对 (nums[i], nums[j]),并满足下述全部条件:
0 <= i < j < nums.length
|nums[i] - nums[j]| == k

  • 要我们查找给定数组中的两个数,它们相差的绝对值为 k
  • 统计满足以上条件的数对的个数
  • 题目中给出的数据可能会有重复的选项,我们要注意去重

解法 Hash表

  • 先用Hash保存所有的数,key为数字本身,value为出现的索引集合Set(主要是为了防止出现扫描到自己的情况)
  • 再次扫描数组,取出 k - nums[i] 在Hash表中保存的数
  • 如果Hash中没有,那么意味着不存在匹配
  • 如果Hash中有的话,我们还需要判断有没有索引是自己的情况,如果索引是当前数,那么就构不成数对,不能满足题意。 综上,代码完成如下:
public class Solution {
    public int findPairs(int[] nums, int k) {
        Map<Integer, Set<Integer>> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            Set<Integer> set = map.computeIfAbsent(num, o -> new HashSet<>());
            set.add(i);
        }
        Map<Integer, Integer> result = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            int left = num - k;
            Set<Integer> set = map.get(left);
            if (set != null) {
                if (set.size() == 1 && set.contains(i)) {
                    continue;
                }
                result.put(num, left);
            }
        }
        return result.size();
    }
}

image.png

排序 + 双指针

题目的两个条件可以理解为:

  • 两个元素的下标值必须不同。当 k = 0 时,数对的两个元素值可以相同,但下标值必须不同。
  • 两个元素差值为 k。 这样一来,我们就不需要关心i和j的大小,只需要i和j的索引不等。差值为 k则可以在排序后使用双指针查询。