zoukankan      html  css  js  c++  java
  • 【LeetCode】18. 4Sum (2 solutions)

    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:

    • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    • 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)

    先确定前两个数num[i],num[j],

    然后设置双指针k,l分别指向两端,往中间扫。

    (1)(sum = num[i]+num[j]+num[k]+num[l]) == taget,则找到其中一个解。k++,l--.

    (2)sum > target, l--

    (3)sum < target, k++

    解法一:

    用map去重

    注:不可以使用unordered_map,不然会报错:

    error C2440: “类型转换”: 无法从“const std::vector<_Ty>”转换为“size_t”

    根据unordered_map的源码来看:

        // TEMPLATE CLASS hash
    template<class _Kty>
        class hash
            : public unary_function<_Kty, size_t>
        {    // hash functor
    public:
        size_t operator()(const _Kty& _Keyval) const
            {    // hash _Keyval to size_t value by pseudorandomizing transform
            ldiv_t _Qrem = _CSTD ldiv((long)(size_t)_Keyval, 127773);
    
            _Qrem.rem = 16807 * _Qrem.rem - 2836 * _Qrem.quot;
            if (_Qrem.rem < 0)
                _Qrem.rem += 2147483647;
            return ((size_t)_Qrem.rem);
            }
        };

    key必须转换为size_t类型,对应于hash表下标。

    保险起见,非内置类型就不要作为unordered_map的key了。

    class Solution {
    public:
        vector<vector<int> > fourSum(vector<int> &num, int target) {
            vector<vector<int> > result;
            if(num.empty() || num.size() < 4)
                return result;
            int size = num.size();
            sort(num.begin(), num.end());
            map<vector<int>, bool> m;
            for(int i = 0; i < size-3; i ++)
            {
                for(int j = i+1; j < size-2; j ++)
                {
                    int k = j+1;    //k < size-1
                    int l = size-1;
                    while(k < l)
                    {
                        int sum = num[i]+num[j]+num[k]+num[l];
                        if(sum == target)
                        {
                            vector<int> cur(4,0);
                            cur[0] = num[i];
                            cur[1] = num[j];
                            cur[2] = num[k];
                            cur[3] = num[l];
                            if(m.find(cur) == m.end())
                            {
                                result.push_back(cur);
                                m[cur] = true;
                            }
                            k ++;
                            l --;
                        }
                        else if(sum > target)
                            l --;
                        else
                            k ++;
                    }
                }
            }
            return result;
        }
    };

    解法二:

    不用开辟新的空间,通过跳过已访问过的元素来去重。

    class Solution {
    public:
        vector<vector<int> > fourSum(vector<int> &num, int target) {
            vector<vector<int> > ret;
            int size = num.size();
            sort(num.begin(), num.end());
            for(int i = 0; i < size; i ++)
            {
                //skip same i
                while(i > 0 && i < size && num[i] == num[i-1])
                    i ++;
                for(int j = i+1; j < size; j ++)
                {
                    //skip same j
                    //attention: the first element (num[i+1]) should not be skipped
                    while(j > i+1 && j < size && num[j] == num[j-1])
                        j ++;
                    
                    int k = j + 1;
                    int l = size - 1;
                    while(k < l)
                    {
                        int sum = num[i] + num[j] + num[k] + num[l];
                        if(sum == target)
                        {
                            vector<int> cur(4);
                            cur[0] = num[i];
                            cur[1] = num[j];
                            cur[2] = num[k];
                            cur[3] = num[l];
                            ret.push_back(cur);
                            k ++;
                            l --;
                            //skip same k
                            while(k < l && num[k] == num[k-1])
                                k ++;
                            //skip same l
                            while(l > k && num[l] == num[l+1])
                                l --;
                        }
                        else if(sum < target)
                        {
                            k ++;
                            //skip same k
                            while(k < l && num[k] == num[k-1])
                                k ++;
                        }
                        else
                        {
                            l --;
                            //skip same l
                            while(l > k && num[l] == num[l+1])
                                l --;
                        }
                    }
                }
            }
            return ret;
        }
    };

  • 相关阅读:
    20191117-STD::讲解及求平均数例题
    计算机网络-ip分类
    游标cursor
    ajax
    django ORM
    urls
    templates
    views
    models
    setting
  • 原文地址:https://www.cnblogs.com/ganganloveu/p/4176281.html
Copyright © 2011-2022 走看看