[LeetCode] 18. 4Sum

思路:
做过3Sum的同学看到这道题的话肯定不会感到困难, 只是在3Sum的基础上再添加一层循环, 时间复杂度O(n^3), 但是根据https://discuss.leetcode.com/topic/28641/my-16ms-c-code的机智思路, 可以在每层循环开始前做几次非常机智的判断, 如果前几个数的和就大于目标值了, 后面肯定更大了, 直接跳出循环. 如果当前值加上尾部的几个值小于目标值, 那么也不用进内层循环了, 也直接做下一次循环就好, 这样节省了大量时间, 真是学习到了! 以后要多注意剪枝

vector<vector<int>> fourSum(vector<int>& nums, int target) {
    vector<vector<int>> res;
    int size = nums.size();
    if (size < 4) return res;
    sort(nums.begin(), nums.end());
    for (int i = 0; i < size - 3; i++) {
        if (i && nums[i] == nums[i - 1]) continue;
        // 精髓之处
        if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break;
        if (nums[i] + nums[size - 1] + nums[size - 2] + nums[size - 3] < target) continue; 
        //
        vector<int> candidate;
        for (int j = i + 1; j < size - 2; j++) {
            if (j > i + 1 && 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[size - 1] + nums[size - 2] < target) continue;
            //
            int TwoSumTarget = target - nums[i] - nums[j];
            int head = j + 1, tail = size - 1;
            while (head < tail) {
                if (nums[head] + nums[tail] == TwoSumTarget) {
                    candidate.push_back(nums[i]);
                    candidate.push_back(nums[j]);
                    candidate.push_back(nums[head]);
                    candidate.push_back(nums[tail]);
                    res.push_back(candidate);
                    candidate.clear();
                    while (head < tail && nums[head + 1] == nums[head]) head++;
                    while (head < tail && nums[tail - 1] == nums[tail]) tail--;
                    head++, tail--;
                }
                else if (nums[head] + nums[tail] < TwoSumTarget) head++;
                else tail--;
            } 
        }
    } 
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值