给定一个包含 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. 响应式编程库RxJava初探

    引子 在读 Hystrix 源码时,发现一些奇特的写法.稍作搜索,知道使用了最新流行的响应式编程库RxJava.那么响应式编程究竟是怎样的呢? 本文对响应式编程及 RxJava 库作一个初步的探索. ...

  2. k8s-jenkins持续发布tomcat项目

    k8s-jenkins持续发布tomcat项目 一.需求 这个实验前期后后搞了很久(公司经常插一些别的事过来,然后自己比较懒,再加上自己知识不够扎实).二进制部署完k8s集群就开始做jenkins持续 ...

  3. Android事件分发机制五:面试官你坐啊

    前言 很高兴遇见你~ 事件分发系列文章已经到最后一篇了,先来回顾一下前面四篇,也当个目录: Android事件分发机制一:事件是如何到达activity的? : 从window机制出发分析了事件分发的 ...

  4. https://www.exploit-db.com/docs/english/45906-cors-attacks.pdf

    https://www.exploit-db.com/docs/english/45906-cors-attacks.pdf What is CORS (cross-origin resource s ...

  5. 目前 c++ primer学习总结笔记

    C++的开始 1 main的返回值:0为成功状态,非0为系统定义的错误类型 2 输入输出:计算结果为左侧运算对象,IO操作读写缓冲与程序中的动作无关 3 输入流istream对象:cin(标准输入): ...

  6. (四)Springboot以jar包方式启动、关闭、重启脚本

    Springboot以jar包方式启动.关闭.重启脚本 1.启动 2.关闭 3.重启 4.脚本授权 SpringBoot: nohup java -jar zlkj-data-server-1.0-S ...

  7. Java面试题及解析

    面试题 解析 1 2 3 Join Sleep-线程睡眠 Yiedld-线程让步 sleep与yield方法区别 isAlive 终止线程 面试题 1.下列单词属于java访问修饰符的有(A,B, C ...

  8. 最新Ceph L版与openstack Pike对接

    安装Ceph luminous   实验环境 三台服务器,每台服务器都有4块硬盘,每台服务器都将自己的第一块硬盘作为系统盘,剩下的做ceph   一.在所有服务器上操作 #使用阿里源 yum inst ...

  9. java架构《并发线程高级篇二》

    本章主要记录讲解并发线程的线程池.使用Executor框架自定义线程池. 自定义线程池使用Queue队列所表示出来的形式: 1 ArrayBlockingQueue<Runnable>(3 ...

  10. f5 http和tcp_80 monitor

    f5上的http和tcp_80 monitor是有区别的.假如使用http为monitor,即使80端口是通的,但是有的情况f5也会根据http的访问返回值情况判断站点不可用. 如, telnet I ...