给定一个包含 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(18)-四数之和的更多相关文章

  1. Java实现 LeetCode 18 四数之和

    18. 四数之和 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target ...

  2. LeetCode 18. 四数之和(4Sum)

    题目描述 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等? ...

  3. [Leetcode 18]四数之和 4 Sum

    [题目] Given an array nums of n integers and an integer target, are there elements a, b, c, and d in n ...

  4. [LeetCode] 18. 四数之和

    题目链接:https://leetcode-cn.com/problems/4sum/ 题目描述: 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个 ...

  5. LeetCode:四数之和【18】

    LeetCode:四数之和[18] 题目描述 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c ...

  6. 【LeetCode】18.四数之和

    题目描述 18. 四数之和 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 t ...

  7. 代码随想录第七天| 454.四数相加II、383. 赎金信 、15. 三数之和 、18. 四数之和

    第一题454.四数相加II 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, ...

  8. 【LeetCode】四数之和

    [问题]给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找 ...

  9. [LeetCode] 4Sum 四数之和

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...

  10. 【LeetCode】四数之和【排序,固定k1,k2,二分寻找k3和k4】

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

随机推荐

  1. ECharts特效-折线图上一个光点来回移动

    参考地址:https://www.makeapie.com/editor.html?c=xxxcG6NGk0 效果图打开上面的网址就可以看到. 核心代码如下,该效果实现的难点是数据的封装,还有eval ...

  2. ADB命令连接逍遥模拟器

    注:打开模拟器开发者模式 ->USB调试模式 1.先进入逍遥模拟器安装目录(MEmu文件夹下),如:D:\Program Files\Microvirt\MEmu 2.在CMD下输入:adb c ...

  3. 让绝对定位的div居中

    最近看到一个问题就是让绝对定位的div居中,在尝试了top:50%:left:50%:后发现,居中是有问题的并不是想象中的样子 需要再加两句margin-top:-盒子高度的一般px  margin- ...

  4. spring restTemplate 进行http请求的工具类封装

    本文为博主原创,未经允许不得转载: 1.对常用调用的方法进行封装: import org.springframework.http.HttpHeaders; import com.alibaba.fa ...

  5. 关闭(隐藏)VS2019控制台上文件路径的显示

    昨天有个朋友问我,怎么关闭在运行程序后,控制台上显示的文件路径啊?啥??我突然不知道他说的说什么,然后我就自己随便打了几行运行了一下,才知道原来他说的是这个: 一开始我也没在意,我就告诉他,这个无所谓 ...

  6. Jenkins ( jenkins+harbor)

    Harbor 是咱们国产的docke仓库具体详细了解请参考以下连接 https://blog.csdn.net/csdn_duomaomao/article/details/78036331 http ...

  7. MapReduce编程练习(四),统计多个输入文件学生的平均成绩,

    问题描述: 在输入文件中,有多个,其中每个输入文件代表一个学生的各科成绩,其中每行的数据形式为<科目,成绩>,你需要将每个文件中的每科目的成绩进行统计,然后求平均值. 输入文件格式: 这里 ...

  8. java导出xls

    package com.spring.mvc.xls; import java.io.File;import java.io.FileInputStream;import java.text.Deci ...

  9. MongoDB:原来我如此简单

    为什么要使用 MongoDB 张三大学毕业设计题目是<XXX博客论坛>,他在存储用户评论的时候遇到了一个问题:这些评论数据量非常大,但是价值不是很大,如果存储在 MySQL 数据库中就会浪 ...

  10. 深入理解nodejs的HTTP处理流程

    目录 简介 使用nodejs创建HTTP服务 解构request 处理Request Body 处理异常 解构response 简介 我们已经知道如何使用nodejs搭建一个HTTP服务,今天我们会详 ...