• 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;
        }
    };






  • 相关阅读:
    第三方驱动备份与还原
    Greenplum 解决 gpstop -u 指令报错
    yum安装(卸载)本地rpm包的方法(卸载本地安装的greenplum 5.19.rpm)
    Java JUC(java.util.concurrent工具包)
    netty 详解(八)基于 Netty 模拟实现 RPC
    netty 详解(七)netty 自定义协议解决 TCP 粘包和拆包
    netty 详解(六)netty 自定义编码解码器
    netty 详解(五)netty 使用 protobuf 序列化
    netty 详解(四)netty 开发 WebSocket 长连接程序
    netty 详解(三)netty 心跳检测机制案例
  • 原文地址:https://www.cnblogs.com/zhxshseu/p/cac3f860d0535ce3571c5cc9e293e5ce.html
Copyright © 2020-2023  润新知