求無序數組中四元素相加等於特定值的所有情況

/***********************************************************************************************
**description:給定一個無序數組和目標數target,要求返回數組中4個元素相加等於target的所有4元素組合
**            要求:4個元素從小到大排列;不能返回重複的4元素組合
**            如:Input: a={1 0 -1 0 -2 2},target=0
**               Output: (-1,0,0,1), (-2,-1,1,2),(-2,0,0,2)
***********************************************************************************************/

#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;

//方法一:先排序,然後對內層左右夾逼
//時間複雜度爲O(n^3)
vector<vector<int>> fourSum_1(vector<int> &arr, int target)
{
    vector<vector<int>> result;
    if (arr.size() < 4)
        return result;
    sort(arr.begin(), arr.end());
    for (int i = 0; i < arr.size() - 3; i++)
    {
        if (i > 0 && arr[i] == arr[i - 1])
            continue;
        for (int j = i + 1; j < arr.size() - 2; j++)
        {
            if (j > i + 1 && arr[j] == arr[j - 1])
                continue;
            int m = j + 1;
            int n = arr.size() - 1;
            while (m < n)
            {
                if (arr[i] + arr[j] + arr[m] + arr[n] < target)
                    m++;
                else if (arr[i] + arr[j] + arr[m] + arr[n] > target)
                    n--;
                else
                {
                    vector<int> group;
                    group.push_back(arr[i]);
                    group.push_back(arr[j]);
                    group.push_back(arr[m]);
                    group.push_back(arr[n]);
                    result.push_back(group);
                    m++;
                    n--;
                    while (arr[m] == arr[m -1])
                        m++;
                }
            }
        }
    }
    return result;
}

//方法二:用hashmap存儲兩個數之和,然後再兩層遍歷從hashmap中找到對應的數據
//時間複雜度:平均O(n^2),最壞O(n^4),空間複雜度:O(n^2)
vector<vector<int>> fourSum_2(vector<int> &arr, int target)
{
    vector<vector<int>> result;
    if (arr.size() < 4)
        return result;
    sort(arr.begin(), arr.end());
    unordered_map<int, vector<pair<int, int>>> cache;
    for (int i = 0; i < arr.size() - 1; i++)
    {
        for (int j = i + 1; j < arr.size(); j++)
        {
            cache[arr[i] + arr[j]].push_back(pair<int, int>(i, j));
        }
    }
    for (int i = 0; i < arr.size(); i++)
    {
        for (int j = i + 1; j < arr.size(); j++)
        {
            int data = target - arr[i] - arr[j];
            if (cache.find(data) != cache.end())
            {
                for (int k = 0; k < cache[data].size(); k++)
                {
                    if (i > cache[data][k].first  && j > cache[data][k].second && i > cache[data][k].second)
                    {
                        vector<int> group;
                        group.push_back(arr[cache[data][k].first]);
                        group.push_back(arr[cache[data][k].second]);
                        group.push_back(arr[i]);
                        group.push_back(arr[j]);
                        result.push_back(group);
                    }
                }
            }
        }
    }
    return result;
}

//方法三:用multi hashmap存儲兩個數之和,然後再兩層遍歷從hashmap中找到對應的數據
//時間複雜度:O(n^2),空間複雜度:O(n^2)
vector<vector<int>> fourSum_3(vector<int> &arr, int target)
{
    vector<vector<int>> result;
    if (arr.size() < 4)
        return result;
    sort(arr.begin(), arr.end());
    unordered_multimap<int, pair<int, int>> cache;
    for (int i = 0; i < arr.size() - 1; i++)
    {
        for (int j = i + 1; j < arr.size(); j++)
        {
            cache.insert(pair<int, pair<int,int>>(arr[i] + arr[j],pair<int,int>(i,j)));
        }
    }
    for (auto i = cache.begin(); i != cache.end(); i++)
    {
        int data = target - i->first;
        auto range = cache.equal_range(data);
        for (auto j = range.first; j != range.second; j++)
        {
            int a = i->second.first;
            int b = i->second.second;
            int c = j->second.first;
            int d = j->second.first;
            if (c > b)
            {
                vector<int> group;
                group.push_back(arr[a]);
                group.push_back(arr[b]);
                group.push_back(arr[c]);
                group.push_back(arr[d]);
                result.push_back(group);
            }
        }
    }
    result.erase(unique(result.begin(), result.end()), result.end());
    sort(result.begin(), result.end());
    return result;
}

發佈了39 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章