LeetCode 18. 4Sum(哈希)

给定一个整数数组`nums`和目标值`target`,寻找所有使四数之和等于`target`的唯一四元组。题目要求解决方案不包含重复的四元组。例如,对于数组`[1, 0, -1, 0, -2, 2]`和`target = 0`,解决方案包括`[-1, 0, 0, 1]`, `[-2, -1, 1, 2]`, 和 `[-2, 0, 0, 2]`。解决此问题的关键在于使用哈希映射存储两数之和及其出现的二元组,然后查找目标和的匹配项。" 80287666,5642401,理解机器学习:感知机算法详解,"['机器学习', '感知机', '分类算法', '模型训练', '统计学习']
摘要由CSDN通过智能技术生成

题目来源:https://leetcode.com/problems/4sum/

问题描述

18. 4Sum

Medium

Given an array nums of n integers and an integer target, are there elements abc, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

The solution set must not contain duplicate quadruplets.

Example:

Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.

 

A solution set is:

[

  [-1,  0, 0, 1],

  [-2, -1, 1, 2],

  [-2,  0, 0, 2]

]

------------------------------------------------------------

题意

给出一个整数序列和一个整数target,求序列中的所有这样的四个数,使得四数之和等于target.

------------------------------------------------------------

思路

用HashMap存储序列中所有二元数对的和[O(n^2)],key为数对和,value为二元组的HashSet,遍历HashMap找到两个数对,其和为target[O(n^2)]。如果二元组的和分布均匀的话,总的复杂度近似为O(n^2).

具体实现上,要注意用HashSet去掉重复的元组。

------------------------------------------------------------

代码

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        int i = 0, j = 0, sum = 0, n = nums.length;
        if (n < 4)
        {
            return Collections.emptyList();
        }
        HashMap<Integer, HashSet<HashSet<Integer>>> twoSum = new HashMap<Integer, HashSet<HashSet<Integer>>>();
        Set<ArrayList<Integer>> retSet = new HashSet<>();
        Set<List<Integer>> ret = new HashSet<>();
        for (i=0; i<n-1; i++)
        {
            for (j=i+1; j<n; j++)
            {
                HashSet<Integer> twoInd = new HashSet<Integer>();
                twoInd.add(i);
                twoInd.add(j);
                sum = nums[i] + nums[j];
                if (twoSum.get(sum) == null)
                {
                    twoSum.put(sum, new HashSet<>());
                }
                twoSum.get(sum).add(twoInd);
            }
        }
        Iterator iter = twoSum.entrySet().iterator();
        while (iter.hasNext())
        {
            HashMap.Entry entry = (HashMap.Entry) iter.next();
            Integer key = (Integer)entry.getKey();
            HashSet<HashSet<Integer>> val1 = (HashSet<HashSet<Integer>>)entry.getValue();
            HashSet<HashSet<Integer>> val2 = twoSum.get(target - key);
            if (val2 == null)
            {
                continue;
            }
            Iterator it1 = val1.iterator();
            while (it1.hasNext())
            {
                HashSet<Integer> set1 = (HashSet<Integer>) it1.next();
                Iterator it2 = val2.iterator();
                while (it2.hasNext())
                {
                    HashSet<Integer> set2 = (HashSet<Integer>) it2.next();
                    HashSet<Integer> Inds = new HashSet<Integer>(set1);
                    Inds.addAll(set2);
                    if (Inds.size() == 4)
                    {
                        ArrayList<Integer> arr = new ArrayList<Integer>();
                        Iterator _iter = Inds.iterator();
                        while (_iter.hasNext())
                        {
                            arr.add(nums[(Integer) _iter.next()]);
                        }
                        Collections.sort(arr);
                        retSet.add(arr);
                    }
                }
            }
        }
        return new LinkedList(retSet);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值