【算法】【线性表】【数组】四数之和

1  题目

给一个包含n个数的整数数组S,在S中找到所有使得和为给定整数target的四元组(a, b, c, d)

四元组(a, b, c, d)中,需要满足 a<=b<=c<=d,答案中不可以包含重复的四元组。

样例 1:

输入:

numbers = [2,7,11,15]
target = 3

输出:

[]

解释:2 + 7 + 11 + 15 != 3,不存在满足条件的四元组。

样例 2:

输入:

numbers = [1,0,-1,0,-2,2]
target = 0

输出:

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

解释:有3个不同的四元组满足四个数之和为0。

2  解答

排序 + 双指针

复制代码
public class Solution {
    /**
     * @param numbers: Give an array
     * @param target: An integer
     * @return: Find all unique quadruplets in the array which gives the sum of zero
     *          we will sort your return value in output
     */
    public List<List<Integer>> fourSum(int[] numbers, int target) {
        // write your code here
        // 1、当数组为空或者元素个数小于4时,直接返回
        List<List<Integer>> res = new ArrayList<>();
        if (numbers == null || numbers.length <= 3) {
            return res;
        }
        // 2、四数之和 相对于三数之和就是固定一个 fixedNum 找三数之和为 target-fixedNum 的
        // 先排序吧
        Arrays.sort(numbers);
        // 四元组要不重复,要去重
        Set<String> strSet = new HashSet<>();
        // 遍历
        for (int i = 0; i < numbers.length; i++) {
            int fixedNum = numbers[i];
            // 计算差值
            int minus = target - fixedNum;
            // 在剩下的找三数之和为 minus 的
            for (int j = i+1; j < numbers.length; j++) {
                // 固定一个,左右指针进行移动
                int num = numbers[j];
                int left = j+1;
                int right = numbers.length-1;
                while (left < right) {
                    int leftNum = numbers[left];
                    int rightNum = numbers[right];
                    int sum = num + leftNum + rightNum;
                    // 小了,左指针++
                    if (sum < minus) {
                        left++;
                    } else if  (sum > minus) {
                        // 大了,右指针--
                        right--;
                    } else {
                        // 相等了 算一种结果 
                        String numStr = String.format("%s%s%s%s", fixedNum, num, leftNum, rightNum);
                        if (!strSet.contains(numStr)) {
                            List<Integer> oneRes = new ArrayList<>();
                            oneRes.add(fixedNum);
                            oneRes.add(num);
                            oneRes.add(leftNum);
                            oneRes.add(rightNum);
                            res.add(oneRes);
                            strSet.add(numStr);
                        }
                        // 因为数组时排序后的,所以这里向中靠拢继续找 左++ 右--
                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }
}
复制代码

加油。

posted @   酷酷-  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示