leetcode 18 4Sum

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

class Solution {
public:
    typedef vector<int>::size_type sz;

    vector<vector<int> > threeSum(vector<int>& nums, int target) {     
        vector<vector<int> > ret;

        for (sz i = 0; i !=  nums.size() - 2; ++i) {
            int twoSum = target - nums[i];
            sz j = i + 1;
            sz k = nums.size() - 1;

            while (j < k) {
                int tmpSum = nums[j] + nums[k];

                if (tmpSum == twoSum) {
                    vector<int> tmp;
                    tmp.push_back(nums[i]);
                    tmp.push_back(nums[j]);
                    tmp.push_back(nums[k]);
                    ret.push_back(tmp);

                     while(j < k && nums[j + 1] == nums[j]) ++j;
                     ++j;

                     while(j < k && nums[k - 1] == nums[k]) --k;
                     --k;
                } else if (tmpSum < twoSum) {
                     while(j < k && nums[j + 1] == nums[j]) ++j;
                     ++j;
                } else {
                     while(j < k && nums[k - 1] == nums[k]) --k;
                     --k;
                }
            }

            while (i + 1 != nums.size() - 2 && nums[i + 1] == nums[i]) ++i;
        }


        return ret;
    }


    vector<vector<int>> fourSum(vector<int>& nums, int target) {

        if (nums.size() < 4) return vector<vector<int> >();

        sort(nums.begin(), nums.end());

        vector<vector<int>> ret;

        for (sz i = nums.size() - 1; i != 2; --i) {
           // vector<int> tmp(nums);
            int tmp = nums[i];
            nums.erase(nums.begin() + i);
            vector<vector<int> > threeV = threeSum(nums, target - nums[i]);

            if (!threeV.empty()) {
                for (sz j = 0; j != threeV.size(); ++j)
                    threeV[j].push_back(tmp);

                copy(threeV.begin(), threeV.end(), back_inserter(ret));
            }
            while (i - 1 != 2 && nums[i] == nums[i - 1]) {
                --i;
                nums.erase(nums.begin() + i);
            };
        }

        return ret;

    }
};

参考后快的不是一丢丢, 34 -> 12

The key point is to add checking at the start of the loop.
At loop 1:

if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) break;
if(nums[i]+nums[n-3]+nums[n-2]+nums[n-1]

class Solution {
public:        
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        typedef vector<int>::size_type sz;

        sz size = nums.size();

        if (nums.size() < 4) return vector<vector<int> >();

        sort(nums.begin(), nums.end());

        vector<vector<int> > ret;

        for (sz i = 0; i != size - 3; ++i) {

            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;

            for (sz j = i + 1; j !=  size - 2; ++j) {             
                int twoSum = target - nums[i] - nums[j];
                sz k = j + 1;
                sz m = size - 1;

                if (nums[i] + nums[j] + nums[k] + nums[k + 1] > target) break;
                if (nums[i] + nums[j] + nums[m] + nums[m - 1] < target) continue;

                while (k < m) {
                    int tmpSum = nums[k] + nums[m];

                    if (tmpSum == twoSum) {
                        ret.push_back(vector<int>{nums[i], nums[j], nums[k], nums[m]});

                         while(k < m && nums[k + 1] == nums[k]) ++k;
                         ++k;

                         while(k < m && nums[m - 1] == nums[m]) --m;
                         --m;
                    } else if (tmpSum < twoSum) {
                         while(k < m && nums[k + 1] == nums[k]) ++k;
                         ++k;
                    } else {
                         while(k < m && nums[m - 1] == nums[m]) --m;
                         --m;
                    }
                }

                while (j + 1 != size - 2 && nums[j + 1] == nums[j]) ++j;
            }

            while (i + 1 != size - 3 && nums[i] == nums[i + 1])  ++i;

        }

        return ret;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值