zoukankan      html  css  js  c++  java
  • 18. 4Sum

    Given an array S of n integers, are there elements abc, 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]
    ]

    分析

    两层循环,然后按照3Sum的做。O(n3)的复杂度。150ms
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    class Solution {
    public:
        vector<vector<int>> fourSum(vector<int>& nums, int target) {
            int len = nums.size();
            vector<vector<int> > result;
            if(len < 4) return result;
            sort(nums.begin(), nums.end());
            for(int i = 0; i < len - 3; ++i){
                if( i > 0 && nums[i] == nums[i - 1]){
                    continue;
                }
                for(int j = i + 1; j < len - 2; ++j){
                    if(j > i + 1 && nums[j] == nums[j - 1]){
                        continue;
                    }
                    int l = j + 1;
                    int r = len - 1;
                    while( l < r){
                        if( nums[i] + nums[j] + nums[l] + nums[r] == target){
                            result.push_back(vector<int>{nums[i], nums[j], nums[l], nums[r]});
                            l++;
                            while( l < r && nums[l] == nums[l - 1])
                                l++;
                        }
                        else if( nums[i] + nums[j] + nums[l] + nums[r] < target){
                            l++;
                        }
                        else{
                            r--;
                        }
                    }
                }
            }
            return result;
        }
    };

    对排序后的数组,进行计算的时候,如果满足 
    1. 最靠前的4个数字之和 > target,则退出计算,因为以后也一定不会满足
    2. 前面的数组和 末尾的数字之和 < target,那么说明肯定中间数字之和一定是 < target的,继续
    1
    2
    if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) break;
    if(nums[i]+nums[len-3]+nums[len-2]+nums[len-1]<target) continue;

    同时优化满足条件的判断顺序以及后续处理,可以得到如下代码:16ms
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    class Solution {
    public:
        vector<vector<int>> fourSum(vector<int>& nums, int target) {
            int len = nums.size();
            vector<vector<int> > result;
            if(len < 4) return result;
            sort(nums.begin(), nums.end());
            for(int i = 0; i < len - 3; ++i){
                if( i > 0 && nums[i] == nums[i - 1]){
                    continue;
                }
                /** cut edge to accelerate the speed **/
                if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) break;
                if(nums[i]+nums[len-3]+nums[len-2]+nums[len-1]<target) continue;
                for(int j = i + 1; j < len - 2; ++j){
                    if(j > i + 1 && nums[j] == nums[j - 1]){
                        continue;
                    }
                    /** cut edge to accelerate the speed **/
                    if(nums[i]+nums[j]+nums[j+1]+nums[j+2]>target) break;
                    if(nums[i]+nums[j]+nums[len-2]+nums[len-1]<target) continue;
                    int l = j + 1;
                    int r = len - 1;
                    while( l < r){
                        int sum = nums[i] + nums[j] + nums[l] + nums[r];
                        if( sum < target){
                            l++;
                        }
                        else if( sum > target){
                            r--;
                        }
                        else{
                            result.push_back(vector<int>{nums[i], nums[j], nums[l], nums[r]});
                            /** cut edge to accelerate the speed **/
                            r--;l++;
                            while( l < r && nums[l] == nums[l - 1])l++;
                            while( l < r && nums[r] == nums[r + 1])r--;
                        }
                    }
                }
            }
            return result;
        }
    };






  • 相关阅读:
    全宁对医药行业销售代表的介绍
    effective c#读书笔记之二 静态成员的初始化
    自学笔记
    effective c#读书笔记之一
    如何判断表中是否有值
    领域驱动
    VIM 打造自己的VIM界面!
    Jqueryui的用法!
    php中io操作!
    php中Http请求!
  • 原文地址:https://www.cnblogs.com/zhxshseu/p/cac3f860d0535ce3571c5cc9e293e5ce.html
Copyright © 2011-2022 走看看