【LeetCode】18. 4Sum

算法小白,最近刷LeetCode。希望能够结合自己的思考和别人优秀的代码,对题目和解法进行更加清晰详细的解释,供大家参考^_^

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]
]

题目意思很清晰,找到所有不重复的四元组,使其和为给定的target

之前做过三个数和的问题(LeetCode 15. 3Sum),参考之前的思路,下意识的以为有O(n^2 * log n)的算法,即按照3Sum的方法找到前三个数的和,再二分查找第四个数就行。再仔细想了一下,发现是不对的,在3Sum问题中,三个数的和是给定的,也就是只有一种情况。在本题中,三个数的和可以有n-1种情况,对每种情况都进行3Sum问题的求解方式,实际的复杂度是O(n^3)

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        size_t len = nums.size();
        sort (nums.begin(), nums.end());  // 排序

        vector<vector<int> > vii;
        for (int i = len - 1; i >= 3; --i){
            int sum3 = target - nums[i];      // 选定第四个数
            for (int j = i - 1; j >= 2; --j){
                int sum2 = sum3 - nums[j];    // 选定第三个数
                int beg = 0, end = j - 1;
                while (beg < end){            // 两个指针指向第一个数和第二个数
                    int tmp_sum = nums[beg] + nums[end];
                    if (tmp_sum > sum2) --end;
                    else if (tmp_sum < sum2) ++beg;
                    else {
                        vector<int> vs({nums[beg], nums[end], nums[j], nums[i]});
                        vii.push_back(vs);
                        // 对前两个数进行去重
                        while (beg < end && nums[beg] == nums[++beg]);
                        while (beg < end && nums[end] == nums[--end]);
                    }
                }
                while (j >= 2 && nums[j] == nums[j-1]) --j;    // 对第三个数进行去重
            }
            while (i >= 3 && nums[i] == nums[i-1]) --i;    // 对第四个数进行去重
        }
        return vii;
    }
};

提交之后,还以为会超时,结果AC了,用时也击败了79%的方案,大致瞟了眼用时最短的代码,貌似也是O(n^3)的复杂度,只是提前对某些不可能的情况进行了处理。

还没查资料,不知道这类题最小的时间复杂度是多少,还有就是扩展到n分元素求和的情况,它的时间复杂度又会是多少

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值