力扣解题思路:532. 数组中的 k-diff 数对 纠错记录

532. 数组中的 k-diff 数对

思路:在这里插入图片描述
首先看我第一版本的错误代码(这里的map可以直接改成set,因为本身也没用到value):

public int findPairs(int[] nums, int k) {
    Map<Integer,Integer> map = new HashMap<>();
    int sum = 0;
    for(int i=0;i<nums.length;i++){
        int a = map.containsKey(nums[i]-k)? 1:0;
        int b = map.containsKey(nums[i]+k)? 1:0;
        sum += (a+b);
        map.put(nums[i],map.getOrDefault(nums[i],0)+1);
    }
    return sum;
}

看似没有问题,实际上当所给数组有重复数字则会计算重复,例如【3,1,4,1,5】2,则会有3,1被重复计算两次。于是我又一想,用set去重不就好了嘛:

public int findPairs(int[] nums, int k) {
    Map<Integer,Integer> map = new HashMap<>();
    Set<int[]> set = new HashSet<>();
    int sum = 0;
    for(int i=0;i<nums.length;i++){
        if(map.containsKey(nums[i]-k)){
            System.out.println("1"+"--"+(nums[i]-k)+"--"+nums[i]);
            set.add(new int[]{nums[i]-k,nums[i]});
        }
        if(map.containsKey(nums[i]+k)){
            System.out.println("2"+"--"+(nums[i]+k)+"--"+nums[i]);
            set.add(new int[]{nums[i]+k,nums[i]});
        }
        map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        System.out.println("3"+"--"+nums[i]+"--"+map.get(nums[i]));
    }
    return set.size();
}

然后仍然错!!我明明去重了呀,然后我把各行print出来,发现这里的set完全没有去重的作用,我恍然大悟,因为set里的元素是数组!所以比较的是地址,自然即使两个数组一样,比较的结果也会不一样!!!所以不能用int[]集合去重。。。

那不行,我必须用set去重!!于是我想了另一个办法,那我就保存数组对的和就行了,和相等不九是重复嘛:

public int findPairs(int[] nums, int k) {
    Map<Integer,Integer> map = new HashMap<>();
    Set<Integer> set = new HashSet<>();
    int sum = 0;
    for(int i=0;i<nums.length;i++){
        if(map.containsKey(nums[i]-k)){
            //System.out.println("1"+"--"+(nums[i]-k)+"--"+nums[i]);
            set.add(nums[i]-k+nums[i]);
        }
        if(map.containsKey(nums[i]+k)){
            //System.out.println("2"+"--"+(nums[i]+k)+"--"+nums[i]);
            set.add(nums[i]+k+nums[i]);
        }
        map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        //System.out.println("3"+"--"+nums[i]+"--"+map.get(nums[i]));
    }
    return set.size();
}

然后就可以啦~~(●ˇ∀ˇ●)

然后再介绍另一种思路,可以免去去重,首先我们重复的原因就是无法预知当前数是否会在后面出现,那我们直接把所有数的个数统计一遍不久可以了嘛:

        Map<Integer,Integer> map=new HashMap<>();
        int count=0;
        if(k<0)return count;
        for(int i=0;i<nums.length;i++){
               map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        }

然后遍历各个数(键):

for(int i:map.keySet()){
    if(k==0){
        if(map.get(i)>1)
        count++;
    }
    else if(map.containsKey(i+k)){
        count++;
    }
}
return count;

注意这里只用判断map.containsKey(i+k)或map.containsKey(i-k)中的一个即可(避免【1,3】【3,1】这种重复)~

另外,还有一题可以用我们第一种错误答案,因为即使有相同的数出现也被视为多种:
在这里插入图片描述

public int subarraySum(int[] nums, int k) {
    Map<Integer, Integer> map = new HashMap<>();
    map.put(0, 1);//必须要有这个0,因为有的sum减去k之后可能等于0,这时如果map里没有0将为出现错误
    int sum = 0, ret = 0;
    for(int i = 0; i < nums.length; ++i) {
        sum += nums[i];
        if(map.containsKey(sum-k))
            ret += map.get(sum-k);
        map.put(sum, map.getOrDefault(sum, 0)+1);
    }
    return ret;
}

这里记得一定要写 map.put(0, 1) ,因为题目场景不一样,上面那个是求树对个数,这个是子数组,单独的一个数也是子数组!所以要设置一个起点 map.put(0, 1) !!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值