每日刷题:第八天 四数相加2

该博客讨论了一种解决四数之和问题的高效方法,不考虑元素重复性。通过将数组分为两组,利用哈希表存储每组的数对之和,并查找相反数对来避免排序,从而降低时间复杂度。代码示例展示了如何用Java实现这一策略,总结了处理这类问题的优化技巧和思路。
摘要由CSDN通过智能技术生成

四数相加,又是加加加一类的哈哈,与之前三数之和四数之和不同,这道题没有要求不能重复,也就是说我们不用对他们进行排序了

思路:一开始想的是三次遍历加哈希值运算,然后看了题解里的一句话

也就是说x个数相加的题目,只要不要求有序,那么我们就可以把他们分为两组,使用map容器,key放相加之后的值,value放出现的次数,然后在第二个map里面寻找key = -key1就好,这是时间复杂度最低的做法

那么为什么是一半左右呢,我们简单举个例子就能解释,例如一共四组,那么加入 1-3分,那么其中一组map的生成的时间复杂度就是n的的三次方,最终的时间复杂度也是n 的三次方,而如果对半分,就只有n平方了,降了一个数量级,所以对半分是为了遍历生成map 的时候尽可能低的数量级。

可以做的优化:

        在生成第二组map 的时候一边生成,一边判断key是否等于前面key 的负数

总结:对于 A+B+...+N = 0   的题目,首先判断结果是否要求无重复

  无重复:那就要对数组进行排序,之后使用双指针加for循环遍历,同时要注意是否重复的问题

  有重复:那么就将所有数组对半分,用两个map容器去承载,之后比较后一个map的key是否是前一个key 的负数即可

贴上通过代码(java)

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        //使用hashMap存下前两组和后两组的和
        Map<Integer,Integer> a1 = toMap(nums1,nums2);
        Map<Integer,Integer> a2 = toMap(nums3,nums4);
        int total = 0;
        //遍历第二个map,直接用哈希运算寻找key=-key1
        for (Map.Entry<Integer, Integer> integerIntegerEntry : a1.entrySet())
        {
            int sum = integerIntegerEntry.getKey();
            if (a2.containsKey(-sum))
                total += a2.get(-sum)*integerIntegerEntry.getValue();
        }
        return total;
    }

    private Map<Integer,Integer> toMap(int[] nums1, int[] nums2)
    {
        //创建结果集
        Map<Integer,Integer> a1 = new HashMap<>();
        //遍历前两组
        for(int i = 0;i < nums1.length;i++)
        {
            for(int j = 0;j < nums2.length;j++)
            {
                //先判断两数之和是否存在
                if (a1.containsKey(nums1[i] + nums2[j]))
                {
                    a1.put(nums1[i] + nums2[j],a1.get(nums1[i] + nums2[j]) + 1);
                }else
                {
                    //不存在
                    a1.put(nums1[i] + nums2[j],1);
                }
            }
        }
        return a1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值