Leetcode.18. 4Sum

题目

给定一个无序数组和一个目标数, 在数组中找到所有4个元素和为目标数的情况, 输出一个二维数组.

Example:
input: [1, 0, -1, 0, -2, 2], 0.
output: [[-1,  0, 0, 1],[-2, -1, 1, 2],[-2,  0, 0, 2]]

思路1

降维, 将求4个元素的和转化为求3个元素的和, 3个元素的求和转化为求2个元素的和.

vector> fourSum(vector& nums, int target) {
    vector> result;
    sort(nums.begin(), nums.end());

    for (int i = 0; i < (int)nums.size() - 3;i++) {
        int first = nums[i];
        if(i> 0 && first == nums[i - 1]) continue;
    
        for (int j = i+1; j < (int)nums.size()- 2;j++) {
            int second = nums[j];
            if(j > i+1 && second == nums[j - 1]) continue;
            int x = target - first - second;
            int l = j + 1, r = (int)nums.size() - 1;
        
            while (l < r) {
                int lNum = nums[l];
                int rNum = nums[r];
                if (lNum + rNum == x) {
                    result.push_back({first, second, lNum, rNum});
                    while(l < r && nums[l] == nums[l + 1]) l++;
                    while(l < r && nums[r] == nums[r - 1]) r--;
                    l++;
                    r--;
                } else if (lNum + rNum > x){
                    r--;
                } else {
                    l++;
                }
            }
        }
    }
    return result;
}

思路2

同思路1, 建立计算三个元素的函数.

思路更加清晰, 便于测试和调试, 但是可能耗费更多内存或者增加函数的耦合.

vector> threeSum(vector& nums, int target, int lastNode) {
    vector> result;

    for (int i = 0; i < (int)nums.size() - 2;i++) {
        if(i> 0 && nums[i] == nums[i - 1]) continue;
        int x = target - nums[i];
        int l = i + 1, r = (int)nums.size() - 1;
    
        while (l < r) {
            int lNum = nums[l];
            int rNum = nums[r];
            if (lNum + rNum == x) {
                result.push_back({nums[i], lNum, rNum, lastNode});
                while(l < r && nums[l] == nums[l + 1]) l++;
                while(l < r && nums[r] == nums[r - 1]) r--;
                l++;
                r--;
            } else if (lNum + rNum > x){
                r--;
            } else {
                l++;
            }
        }
    }
    return result;
}

vector> fourSum(vector& nums, int target) {
    vector> result;
    if (nums.size() < 4) {
        return result;
    }
    sort(nums.begin(), nums.end());

    for (int i = 0; i < (int)nums.size() - 3;i++) {
        if(i> 0 && nums[i] == nums[i - 1]) continue;
        int tempTarget = target-nums[i];
    
        vector tempNums = nums;
        tempNums.erase(tempNums.begin(), tempNums.begin()+i+1);
    
        vector> temp = threeSum(tempNums, tempTarget, nums[i]);
        for (vector vec : temp) {
            result.push_back(vec);
        }
    }
    return result;
}

总结

拆解问题, 将复杂问题转化为简单问题, 将高维问题转化为低维问题.

考虑好边界问题和特殊情况.尽量减少循环的计算量.

你可能感兴趣的:(Leetcode.18. 4Sum)