列表

详情


18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

你可以按 任意顺序 返回答案 。

 

示例 1:

输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例 2:

输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

 

提示:

相似题目

两数之和

三数之和

四数相加 II

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { } };

javascript 解法, 执行用时: 60 ms, 内存消耗: 43.2 MB, 提交时间: 2023-07-15 09:10:22

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[][]}
 */
var fourSum = function (nums, target) {
    nums.sort((a, b) => a - b);
    const n = nums.length;
    let ans = [];
    for (let a = 0; a < n - 3; a++) { // 枚举第一个数
        const x = nums[a]; // 使用 long long 避免溢出
        if (a > 0 && x === nums[a - 1]) continue; // 跳过重复数字
        if (x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target) break; // 优化一
        if (x + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) continue; // 优化二
        for (let b = a + 1; b < n - 2; b++) { // 枚举第二个数
            const y = nums[b];
            if (b > a + 1 && y === nums[b - 1]) continue; // 跳过重复数字
            if (x + y + nums[b + 1] + nums[b + 2] > target) break; // 优化一
            if (x + y + nums[n - 2] + nums[n - 1] < target) continue; // 优化二
            let c = b + 1, d = n - 1;
            while (c < d) { // 双指针枚举第三个数和第四个数
                const s = x + y + nums[c] + nums[d]; // 四数之和
                if (s > target) d--;
                else if (s < target) c++;
                else { // s == target
                    ans.push([x, y, nums[c], nums[d]]);
                    for (c++; c < d && nums[c] === nums[c - 1]; c++); // 跳过重复数字
                    for (d--; d > c && nums[d] === nums[d + 1]; d--); // 跳过重复数字
                }
            }
        }
    }
    return ans;
};

golang 解法, 执行用时: 4 ms, 内存消耗: 2.6 MB, 提交时间: 2023-07-15 09:10:08

func fourSum(nums []int, target int) (ans [][]int) {
    sort.Ints(nums)
    n := len(nums)
    for a := 0; a < n-3; a++ { // 枚举第一个数
        x := nums[a]
        if a > 0 && x == nums[a-1] { // 跳过重复数字
            continue
        }
        if x+nums[a+1]+nums[a+2]+nums[a+3] > target { // 优化一
            break
        }
        if x+nums[n-3]+nums[n-2]+nums[n-1] < target { // 优化二
            continue
        }
        for b := a + 1; b < n-2; b++ { // 枚举第二个数
            y := nums[b]
            if b > a+1 && y == nums[b-1] { // 跳过重复数字
                continue
            }
            if x+y+nums[b+1]+nums[b+2] > target { // 优化一
                break
            }
            if x+y+nums[n-2]+nums[n-1] < target { // 优化二
                continue
            }
            c, d := b+1, n-1
            for c < d { // 双指针枚举第三个数和第四个数
                s := x + y + nums[c] + nums[d] // 四数之和
                if s > target {
                    d--
                } else if s < target {
                    c++
                } else {
                    ans = append(ans, []int{x, y, nums[c], nums[d]})
                    for c++; c < d && nums[c] == nums[c-1]; c++ {} // 跳过重复数字
                    for d--; d > c && nums[d] == nums[d+1]; d-- {} // 跳过重复数字
                }
            }
        }
    }
    return
}

java 解法, 执行用时: 2 ms, 内存消耗: 42.8 MB, 提交时间: 2023-07-15 09:09:54

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<>();
        int n = nums.length;
        for (int a = 0; a < n - 3; a++) { // 枚举第一个数
            long x = nums[a]; // 使用 long 避免溢出
            if (a > 0 && x == nums[a - 1]) continue; // 跳过重复数字
            if (x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target) break; // 优化一
            if (x + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) continue; // 优化二
            for (int b = a + 1; b < n - 2; b++) { // 枚举第二个数
                long y = nums[b];
                if (b > a + 1 && y == nums[b - 1]) continue; // 跳过重复数字
                if (x + y + nums[b + 1] + nums[b + 2] > target) break; // 优化一
                if (x + y + nums[n - 2] + nums[n - 1] < target) continue; // 优化二
                int c = b + 1, d = n - 1;
                while (c < d) { // 双指针枚举第三个数和第四个数
                    long s = x + y + nums[c] + nums[d]; // 四数之和
                    if (s > target) d--;
                    else if (s < target) c++;
                    else { // s == target
                        ans.add(List.of((int) x, (int) y, nums[c], nums[d]));
                        for (c++; c < d && nums[c] == nums[c - 1]; c++) ; // 跳过重复数字
                        for (d--; d > c && nums[d] == nums[d + 1]; d--) ; // 跳过重复数字
                    }
                }
            }
        }
        return ans;
    }
}

python3 解法, 执行用时: 64 ms, 内存消耗: 16 MB, 提交时间: 2023-07-15 09:09:34

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        ans = []
        n = len(nums)
        for a in range(n - 3):  # 枚举第一个数
            x = nums[a]
            if a and x == nums[a - 1]:  # 跳过重复数字
                continue
            if x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target:  # 优化一
                break
            if x + nums[-3] + nums[-2] + nums[-1] < target:  # 优化二
                continue
            for b in range(a + 1, n - 2):  # 枚举第二个数
                y = nums[b]
                if b > a + 1 and y == nums[b - 1]:  # 跳过重复数字
                    continue
                if x + y + nums[b + 1] + nums[b + 2] > target:  # 优化一
                    break
                if x + y + nums[-2] + nums[-1] < target:  # 优化二
                    continue
                # 双指针枚举第三个数和第四个数
                c = b + 1
                d = n - 1
                while c < d:
                    s = x + y + nums[c] + nums[d]  # 四数之和
                    if s > target:
                        d -= 1
                    elif s < target:
                        c += 1
                    else:  # s == target
                        ans.append([x, y, nums[c], nums[d]])
                        c += 1
                        while c < d and nums[c] == nums[c - 1]:  # 跳过重复数字
                            c += 1
                        d -= 1
                        while d > c and nums[d] == nums[d + 1]:  # 跳过重复数字
                            d -= 1
        return ans

python3 解法, 执行用时: 84 ms, 内存消耗: 14.7 MB, 提交时间: 2022-07-28 15:28:12

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        quadruplets = list()
        if not nums or len(nums) < 4:
            return quadruplets
        
        nums.sort()
        length = len(nums)
        for i in range(length - 3):
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            if nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target:
                break
            if nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target:
                continue
            for j in range(i + 1, length - 2):
                if j > i + 1 and nums[j] == nums[j - 1]:
                    continue
                if nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target:
                    break
                if nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target:
                    continue
                left, right = j + 1, length - 1
                while left < right:
                    total = nums[i] + nums[j] + nums[left] + nums[right]
                    if total == target:
                        quadruplets.append([nums[i], nums[j], nums[left], nums[right]])
                        while left < right and nums[left] == nums[left + 1]:
                            left += 1
                        left += 1
                        while left < right and nums[right] == nums[right - 1]:
                            right -= 1
                        right -= 1
                    elif total < target:
                        left += 1
                    else:
                        right -= 1
        
        return quadruplets

上一题