给定一个包含 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. WMIC 查看bios配置信息

    如何查看我们的主板上的BIOS信息呢?有办法,不用安装任何软件,只需要windows自带的命令提示符就行,哈哈 WMIC BIOS LIST FULL /FORMAT:VALUE 如果第一次使用wmi ...

  2. JavaScript中eval的替代方法

    引自:https://www.cnblogs.com/lxg0/p/7805266.html 通常我们在使用ajax获取到后台返回的json数据时,需要使用 eval 这个方法将json字符串转换成对 ...

  3. Python 身份证校验代码

    Python 身份证校验代码 居民身份证bai编号识别 1.身份证编码规则如下:根据[中华人民共和国国家标准GB11643-1999]中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本 ...

  4. JSAAS BPM快速开发平台-企业管理软件,专属你的企业管家

    前言: 2020年,企业该如何去选择合适的信息化规划管理软件,基于目前社会软件杂乱无章,选择企业业务贴近的管理软件,甚是困难,市场上一些大品牌公司的产品,定位高,价格高,扩展难,等等一系列的问题,对于 ...

  5. Jmeter如何录制APP客户端脚本

    简单五步教大家Jmeter录制APP客户端脚本: Step1 右键单击该测试计划,选择"添加"-"线程组",添加一个线程组. Step2 为了录制客户端的操作, ...

  6. Code Review 的几个技巧

    No magic: Explicit not implicit: 覆盖度比深度重要,覆盖度追求100%: 频率比仪式感重要,坐公交蹲厕所打开手机都可以 Review 别人代码,不需要专门组织会议: 粒 ...

  7. Spring Data JPA基本增删改查和JPQL查询(含完整代码和视频连接)

    问题:SpringDataJPA怎么使用? 一.考察目标 主要考核SpringDataJPA的用法 二.题目分析 spring data jpa 的使用步骤(下面有具体实现细节) 1.创建maven工 ...

  8. 两个报文是如何进行 TCP 分组传输

    16 | 如何理解TCP的"流"? https://time.geekbang.org/column/article/132443 TCP 是一种流式协议在前面的章节中,我们讲的都 ...

  9. 从tcp层面研究java socket 的使用

    本文主要通过wireshark抓包来分析java socket程序的一些细节, 解决以前的一些疑问: 1.当一方的socket先关闭后,另一方尚未关闭的socket 还能做什么? 2.当基于socke ...

  10. 页面渲染html的过程

    浏览器渲染页面的一般过程: 1.浏览器解析html源码,然后创建一个 DOM树.并行请求 css/image/js在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文 ...