zoukankan      html  css  js  c++  java
  • Leetcode(18)-四数之和

    给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

    注意:

    答案中不可以包含重复的四元组。

    示例:

    给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
    
    满足要求的四元组集合为:
    [
      [-1,  0, 0, 1],
      [-2, -1, 1, 2],
      [-2,  0, 0, 2]
    ]

    思路:

    (1)我们可以用递归的方法。将四数之和转换为三数之和,然后转换为两数之和。先将数组中的数排序,然后调用函数处理。这样就需要一个函数,个数和目标值都通过传参的方式获取。还需要一个开始的位置,也通过参数传递进去。如果刚好转换的是两数之和,那么我们可以利用前面已经解决过的两数之和的方法来处理,用unordered_set来处理重复的元素,判断有没有被访问过,以免一个元素重复使用。如果不是两个数的和,那么我们将这个数先记下来,直到是判断两个数的和。总之就是先固定两个数,然后用two-sum的方法来找另外两个数。

      vector<vector<int>> k_Sum(vector<int> &nums, int begPos, int count, int target)
        {
            if (nums.empty())
                return vector<vector<int>>();
            /*所输入序列为已排序*/
            int len = nums.size();
            unordered_set<int> visited;
            vector<vector<int>> ret;
            vector<int> tmp;
            /*2-sum 处理*/
            if (2 == count)
            {
                int i = begPos, j = len - 1;
                while (i < j)
                {
                    int sum = nums[i] + nums[j];
                    if (sum == target && visited.find(nums[i]) == visited.end())
                    {
                        tmp.clear();
                        tmp.push_back(nums[i]);
                        tmp.push_back(nums[j]);
                        ret.push_back(tmp);
    
                        /*加入已访问set*/
                        visited.insert(nums[i]);
                        visited.insert(nums[j]);
    
                        ++i;
                        --j;
                    }//if
                    else if (sum < target)
                        ++i;
                    else
                        --j;
                }//while
            }//if
            else{
                for (int i = begPos; i < len; ++i)
                {
                    if (visited.find(nums[i]) == visited.end())
                    {
                        visited.insert(nums[i]);
                        /*得到k-1 sum的序列*/
                        vector<vector<int>> subRet = k_Sum(nums, i+1, count - 1, target-nums[i]);
                        if (!subRet.empty())
                        {
                            int sz = subRet.size();
                            for (int j = 0; j < sz; ++j)
                            {
                                subRet[j].insert(subRet[j].begin(), nums[i]);
                            }//for
                            ret.insert(ret.end(), subRet.begin(), subRet.end());
                        }//if
                    }//if
                }//for
            }//else
            /*返回结果集*/
            return ret;
        }
        /*4-sum算法,递归实现,TLE*/
        vector<vector<int>> fourSum(vector<int>& nums, int target) {
            if (nums.empty())
                return vector<vector<int>>();
    
            sort(nums.begin(), nums.end());
    
            return k_Sum(nums, 0, 4, target);
        }

    (2)思路是一样的,但是没有用递归的方式

        vector<vector<int>> fourSum(vector<int>& nums, int target)
        {
            if (nums.empty() || nums.size() < 4)
                return vector<vector<int>>();
    
            sort(nums.begin(), nums.end());
            int len = nums.size();
            set<vector<int>> tmpRet;
            vector<vector<int>> res;
    
            for (int i = 0; i < len; ++i)
            {
                for (int j = i + 1; j < len; ++j)
                {
                    int beg = j + 1, end = len - 1;
                    while (beg < end)
                    {
                        int sum = nums[i] + nums[j] + nums[beg] + nums[end];
                        if (sum == target)
                        {
                            vector<int> tmp;
                            tmp.push_back( nums[i]);
                            tmp.push_back( nums[j]);
                            tmp.push_back( nums[beg]);
                            tmp.push_back( nums[end]);
    
                            tmpRet.insert(tmp);
    
                            ++beg;
                            --end;
                        }
                        else if (sum < target)
                        {
                            ++beg;
                        }
                        else
                            --end;
                    }//while
                }//for
            }//for
            auto iter = tmpRet.begin();
            while (iter != tmpRet.end())
            {
                res.push_back(*iter);
                ++iter;
            }//while
            return res;
        }
  • 相关阅读:
    leetcode
    vue初尝试--组件
    vue初尝试--项目结构
    vue初尝试--新建项目
    SQL取xml中节点值
    UI设计
    Asp.NET中Gridview CSS---Office2003风格
    Jquery+JSON+WebService使用总结
    ASP.NET 如何固定表格表头(fixed header)
    项目总结
  • 原文地址:https://www.cnblogs.com/mini-coconut/p/9193206.html
Copyright © 2011-2022 走看看