4Sum - LeetCode

Posted 真子集

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4Sum - LeetCode相关的知识,希望对你有一定的参考价值。

题目链接

Merge Two Sorted Lists - LeetCode

注意点

  • 和3Sum那道题一样

解法

解法一:在3Sum的基础上再加一层循环即可。时间复杂度为O(n^3)

class Solution {
public:
    using num_t = vector<int>;
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size(),newTarget,i = n-1,j,l,r;
        vector<num_t> ans;
        if(n < 4) return ans;
        sort(nums.begin(),nums.end());
        while(i >= 3)
        {
            newTarget = target - nums[i];
            j = i-1;
            while(j >= 2)
            {
                l = 0;
                r = j-1;
                while(l < r)
                {
                    int sum = nums[l]+nums[r]+nums[j];
                    if(sum < newTarget) l++;
                    else if(sum > newTarget) r--;
                    else
                    {
                        ans.push_back({nums[i],nums[j],nums[l],nums[r]});
                        l++;
                        r--;
                        while (l<r && nums[l-1]==nums[l]) l++;     
                        while (l<r && nums[r+1]==nums[r]) r--;
                    }
                }
                j--;
                while(j >= 2 && nums[j+1]==nums[j]) j--;
            }
            i--;
            while(i >= 3 && nums[i+1]==nums[i]) i--;
        }
        return ans;
    }
};

解法二:看了评论得到的思路。先二重循环,将所有可能出现的两数之和的值map保存。然后再二重循环,计算两数之和,比较加上map中存的值之后是否等于target。时间复杂度为O(n^2)

class Solution {
public:
    using num_t = vector<int>;
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<num_t> ret;
        int n = nums.size(),i,j;
        if(n < 4) return ret;
        unordered_map<int,vector<pair<int,int>>> myMap;
        for(i = 0;i < n;i++)
        {
            for(j = i+1;j < n;j++)
            {
                myMap[target - nums[i] - nums[j]].push_back({i,j});
            }
        }
        for(i = 0;i < n;i++)
        {
            for(j = i+1;j < n;j++)
            {
                int temp = nums[i] + nums[j];
                if(myMap.count(temp))
                {
                    for(auto p:myMap[temp])
                    {
                        if(p.first != i && p.first != j && p.second != i && p.second != j)
                        {
                        ret.push_back({nums[p.first],nums[p.second],nums[i],nums[j]});
                        }
                    }
                }
            }
        }
        n = ret.size();
        for(i = 0;i < n;i++)
        {
            sort(ret[i].begin(),ret[i].end());
        }
        sort(ret.begin(),ret.end());
        ret.erase(unique(ret.begin(),ret.end()),ret.end());
        
        return ret;
    }
};

注:虽然这道题时间复杂度为O(n2)但是去重所花的时间过多,导致最终所花时间甚至高于O(n3)
再注:去重所花时间是固定的,取决于输入的数组长度。所以在求nSum的问题的时候,随着n的增大,解法二更有优势。

小结

  • unique函数
  • map中key对应的value是唯一的,如果想一个key对应多个value可以像解法二一样,构造一个map<int,vector<int>>

以上是关于4Sum - LeetCode的主要内容,如果未能解决你的问题,请参考以下文章

[Leetcode] 4Sum

leetcode 18 4Sum

LeetCode——18. 4Sum

LeetCode - 18. 4Sum

Leetcode018 4Sum

LeetCode(16. 4Sum)