No.018:4Sum
问题:
Given an array S of n integers, are there elements a, b, c, 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: 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]
]
官方难度:
Medium
翻译:
给定一个长度为n的无序数组S和目标数字target,在数组S中找出4个整数a,b,c,d,使a+b+c+d=target。
找出所有的可能解,且解集中不包含重复项。
例子:
数组S:{ 1, 0, -1, 0, -2, 2},目标值target=0。
解集为[ [-1,0,0,1],[-2,-1,1,2],[-2,0,0,2] ]。
- 显然,本题是No.001(Two Sum),No.015(3Sum),No.016(3Sum Closest)更深一步的讨论。在解决这道问题时,不妨考虑一种解法,适用于5Sum,6Sum之后一系列的问题。我可以将这些问题总结归纳为:kSum问题,k>=2。
- 显然是需要使用递归,而递归的终点就是2Sum问题。
- 将递归方法独立出来,在进入递归之前,优先给数组排序(如k=2,这种做法会略微影响性能)。
- 2Sum问题,仍然使用夹逼的原则,同时维护两侧的previous值。增加优化策略:当前左值大于目标数且当前左值大于0,return;当2倍前左值大于目标值,或2倍当前右值小于目标值,return。
- 当k>2时,做类似2Sum的优化策略,将当前目标值-当前值,作为递归入参的目标值,同时传入当前索引值,进行递归。
- 获得递归的解集,循环加入当前值到解集中返回。
- 注意入参检查。
解题代码:
public static List<List<Integer>> fourSum(int[] nums, int target) {
if (nums == null || nums.length < 4) {
throw new IllegalArgumentException("Input error");
}
Arrays.sort(nums);
return kSum(nums, 0, target, 4);
}
private static List<List<Integer>> kSum(int[] nums, int startIndex, int target, int kSum) {
List<List<Integer>> result = new LinkedList<>();
// 递归终点是2Sum问题
if (kSum == 2) {
int left = startIndex, right = nums.length - 1;
int preLeft = Integer.MIN_VALUE, preRight = Integer.MIN_VALUE;
while (left < right) {
if (nums[left] > target && nums[left] > 0) {
return result;
}
if (2 * nums[left] > target || 2 * nums[right] < target) {
return result;
}
if (nums[left] == preLeft) {
left++;
continue;
}
if (nums[right] == preRight) {
right--;
continue;
}
int sum = nums[left] + nums[right];
if (sum == target) {
List<Integer> list = new LinkedList<>();
list.add(nums[left]);
list.add(nums[right]);
result.add(list);
}
if (sum < target) {
preLeft = nums[left];
left++;
} else {
preRight = nums[right];
right--;
}
}
} else {
// 大于2Sum问题,使用递归
int previous = Integer.MAX_VALUE;
for (int i = startIndex; i < nums.length - 1; i++) {
if (nums[i] > target && nums[i] > 0) {
return result;
}
// target值的范围超过k个极值
if (kSum * nums[i] > target || kSum * nums[nums.length - 1] < target) {
return result;
}
if (nums[i] == previous) {
continue;
}
int tempTarget = target - nums[i];
// 开启递归
List<List<Integer>> tempResult = kSum(nums, i + 1, tempTarget, kSum - 1);
for (List<Integer> a : tempResult) {
a.add(nums[i]);
result.add(a);
}
previous = nums[i];
}
}
return result;
}
fourSum
相关链接:
https://leetcode.com/problems/4sum/
PS:如有不正确或提高效率的方法,欢迎留言,谢谢!
No.018:4Sum的更多相关文章
- Python练习题 018:打印星号菱形
[Python练习题 018] 打印出如下图案(菱形): * *** ***** ******* ***** *** * --------------------------------------- ...
- LeetCode第[18]题(Java):4Sum 标签:Array
题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...
- C++笔记018:构造函数的调用规则
原创笔记,转载请注明出处! 点击[关注],关注也是一种美德~ 一.默认构造函数 两个特殊的构造函数 1.默认无参构造函数 当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空 ...
- Python3练习题 018:打印星号菱形
Python的内置方法 str.center(width [, fillchar]) 就能轻而易举打印出来:str即是数量不等的星号,width即是最大宽度(7个空格),默认填充字符fillchar就 ...
- 018:InnoDB 存储引擎、表空间
目录 一.InnoDB 存储引擎 1. InnoDB的历史 2. InnoDB的特点 3. InnoDB存储引擎的文件 3.1 概述 3.2 InnoDB - 表空间 3.3 General表空间 3 ...
- LeetCode OJ:4Sum(4数字之和)
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...
- 018:include函数详解
include函数详解(了解——虽然用的很少): include函数的用法,目前有三种使用方式: 1.include(module,namespace=None): module:子url的模块字符串 ...
- LeetCode18: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 ...
- ELK学习实验018:filebeat收集docker日志
Filebeat收集Docker日志 1 安装docker [root@node4 ~]# yum install -y yum-utils device-mapper-persistent-data ...
随机推荐
- Lucene学习
一.全文索引的原理 数据存在形式: 1.结构化数据: 指具有固定格式或有限长度的数据,如数据库,元数据等. 2.非结构化数据(全文数据): 指不定长或无固定格式的数据,如邮件,word文档等. 3.半 ...
- JDBC操作数据库,第一:jsp插入mysql数据库,坎坷摸索分享
JSP连接数据库,坎坷摸索了好久,现在终于做好了,分享一下,希望对更多热爱编程学习的人有所帮助!!!谢谢 第一:首先准备的就是已经安装好Mysql,这里不做多叙述,百度可以做到. 然后在mysql数据 ...
- vs xamarin android 监听返回键退出程序
public override bool OnKeyDown([GeneratedEnum]Keycode keyCode, KeyEvent e) { if (keyCode == Keycode. ...
- Linux的学习--配置LNMP环境
最近,回到公司,发现电脑都换成linux系统了...很无力... 配置环境,跑起项目来就花了一天...额...在这里记录一下-- 系统是ubuntu 12.04. 一.安装nginx1:ubuntu因 ...
- C++智能指针简单剖析
导读 最近在补看<C++ Primer Plus>第六版,这的确是本好书,其中关于智能指针的章节解析的非常清晰,一解我以前的多处困惑.C++面试过程中,很多面试官都喜欢问智能指针相关的问题 ...
- android.os.networkonmainthreadexception怎么解决
在android2.3以后,在主线程中必须使用另一个线程,如handler机制,或者异步任务获取网络数据. 如果你的访问网络操作必须放在主线程中执行,那么在onCreate()中添加 if (GetV ...
- 常用的Webservice接口
常用的Webservice接口 . 查询手机:http://www.yodao.com/smartresult-xml/search.s?type=mobile&q=手机号码 . 查询IP:h ...
- 【Android】[转] ANR的分析和问题处理
一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1. KeyDispatchTimeout(5 seconds) ...
- SQL SERVER 内存分配及常见内存问题 DMV查询
内存动态管理视图(DMV): 从sys.dm_os_memory_clerks开始. SELECT [type] , SUM(virtual_memory_reserved_kb) AS [VM R ...
- Azure China (1) Azure公有云落地中国
<Windows Azure Platform 系列文章目录> 微软公有云Microsoft Azure已经落地中国,官方网址:http://www.windowsazure.cn/. 在 ...