4Sum-LeetCode

来源:互联网 发布:大数据概念股一览表 编辑:程序博客网 时间:2024/06/06 01:49

-8,-2,-1,4,5,5,6,12,16


思路:

1) 先排序

2) 注意排除重复元素。

    从后往前 for(int i =nums.size()-1;i > 2; i--)  注意这里至少要剩三个元素。

    每一个元素nums[i],找出对应的ThreeSum(nums, i-1, target - nums[i])。 要把当前的元素坐标传入,因为要在此元素之前找三个三个的对。

3) ThreeSum

    注意排除重复元素。

    从后往前 for(int i = nums.size()-1; i > 1; i--)  注意这里至少要剩两个元素。

    每一个元素nums[i],找出对应的TwoSum(nums, i-1, target - nums[i])。 要把当前的元素坐标传入,因为要在此元素之前找两个两个的对。

4) 求TwoSum

用两个指针,对在区间范围内的数找,是否两个相加为target。若是target接着往后找! 

注意排除重复元素

<gs id="61339a29-ab6b-4098-910a-2a1a608efdac" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">while</gs><gs id="55c01370-ebf5-47f6-90b9-36fb4e418a6e" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">(</gs>l < r && <gs id="d462942d-e4d6-4126-9f7b-670abbb95d29" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">nums</gs><gs id="9101631a-5b48-41a9-859b-50ed5e09d02b" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">[</gs>l<gs id="2d393698-9d1e-4c1f-a01f-839ec97ba982" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">]</gs>==nums<gs id="b314f502-c008-4dff-9059-1a716ba5abe4" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">[</gs>l-1]) l++;        while<gs id="5ca59368-cd72-486b-8949-7674f174be68" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">(</gs>l < r && <gs id="f5113591-bce9-4238-8d51-457db2db7d6e" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">nums</gs><gs id="906b594b-b9e9-4c25-bc6a-cd9c33bc0012" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">[</gs>r<gs id="4e7dbadb-0398-436e-9ef4-a5c09a3a140e" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">]</gs>==nums<gs id="35570073-98e1-4378-b0d6-016cf8987d1f" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">[</gs>r+1]) <gs id="98ac0f0d-a4de-4b0c-b013-32d377eebe2e" ginger_software_uiphraseguid="638a474f-7fa4-4cad-855f-332a0b980064" class="GINGER_SOFTWARE_mark">r</gs>--;

外层循环i从后往前扫是因为,每次要把大的元素放在后面。

内层寻缘j从前往后扫是因为,要把最小的pair放在前面。



时间复杂度:

由于最后一次TwoSum用的是夹逼方法O(n), 所以是O(n^3)。

如果用brute force,把所有可能的四个数字都算一遍是O(n^4)。



Code (C++):

class Solution {public:    vector<vector<int>> fourSum(vector<int>& nums, int target) {        vector<vector<int>> res;        if(nums.size()== 0 || <strong>nums.size() < 4</strong>) return res;        sort(nums.begin(), nums.end());        for(int i = nums.size()-1; <strong>i > 2</strong>; i--)  //at least 0,1,2        {            <strong>if(i < nums.size()-1 && nums[i]==nums[i+1]) continue;</strong>            vector<vector<int> > three = threeSum(nums, <strong>i-1</strong>, target - nums[i]); // search three pairs from i-1            for(int j = 0; j < three.size(); j++)            {                three[j].push_back(nums[i]);//最小的三个,要有次序的,加上最大的元素                res.push_back(three[j]);            }        }        return res;    }    vector<vector<int>> threeSum(vector<int>& nums, int end, int target)    {        vector<vector<int> > res;        for(int i = end; <strong>i > 1</strong>; i--)        {            <strong>if(i < end && nums[i] == nums[i+1]) continue;</strong>            vector<vector<int> > two = twoSum(nums, i-1, target - nums[i]);             for(int j = 0; j< two.size(); j++)            {                two[j].push_back(nums[i]);                res.push_back(two[j]);            }        }        return res;    }    vector<vector<int>> twoSum(vector<int>& nums, int end, int target)    {        int l = 0;        int r = end;        vector<int> tmp;        vector<vector<int> > res;        while(l < r)        {                        if(nums[l]+nums[r] == target)            {                tmp.push_back(nums[l]);                tmp.push_back(nums[r]);                res.push_back(tmp);                tmp.clear();                //接着往后,找到才算数。                <strong>l++;                r--;                while(l < r && nums[l]==nums[l-1]) l++;                while(l < r && nums[r]==nums[r+1]) r--;</strong>            }            else if(nums[l]+nums[r] > target) r--;            else l++;                    }        return res;    }};


0 0