leetcode 18 4Sum

本文详细介绍了 LeetCode 上的 4Sum 问题解决方法,通过二分查找的方式预先枚举并排序 a+b 的组合,再判断是否存在 a+b=target-c-d。文章提供了 C++ 代码示例,并考虑了结果去重的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode 18 4Sum

原题链接:https://leetcode.com/problems/4sum/

Description

Given an array S of n integers, are there elements a,b,c, and d in S 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.

For example, given array S=[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]
]

Solution

二分查找,先预先枚举出 a+b 所得的 n2 个数字并排好序。
然后判断是否有 a+b=targetcd (二分查找即可)
PS: 注意所求的四个数下标各不相同,枚举的时候要加以判断
PPS: 所得结果可能需要去重。

class Solution {
    using vec = vector<int>;
    using mat = vector<vec>;
    using pii = pair<int, pair<int, int>>;
public:
    mat fourSum(vec& nums, int target) {
        mat res;
        int n = 0;
        if(!(n = nums.size()) || n < 4) return res;
        vector<pii> vpi;
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                vpi.push_back({ nums[i] + nums[j], { i, j } });
            }
        }
        sort(vpi.begin(), vpi.end(), [](pii &a, pii &b)->bool {
            return a.first < b.first;
        });
        int size = vpi.size();
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                int lb = 0, ub = size - 1;
                int k = target - nums[i] - nums[j];
                while(lb <= ub) {
                    int m = (lb + ub) >> 1;
                    if(vpi[m].first >= k) ub = m - 1;
                    else lb = m + 1;
                }
                while(lb < size && vpi[lb].first == k) {
                    auto &r = vpi[lb++].second;
                    if(r.first == i || r.first == j || r.second == i || r.second == j) continue;
                    int a = nums[i], b = nums[j], c = nums[r.first], d = nums[r.second];
                    if(a + b + c + d != target) continue;
                    if (a > b) swap(a, b);
                    if (c > d) swap(c, d);
                    if (a > c) swap(a, c);
                    if (b > d) swap(b, d);
                    if (b > c) swap(b, c);
                    res.push_back({ a, b, c, d });
                }
            }
        }
        sort(res.begin(), res.end());
        res.erase(unique(res.begin(), res.end()), res.end());
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值