LeetCode 18 4Sum (4个数字之和等于target)
题目链接 https://leetcode.com/problems/4sum/?tab=Description
找到数组中满足 a+b+c+d=0的所有组合,要求不重复。
Basic idea is using subfunctions for 3sum and 2sum, and keeping throwing all impossible cases. O(n^3) time complexity, O(1) extra space complexity.
首先进行判断,由于是四个数相加等于target,其中可以通过判断剪去一些不必要的分支:
for (i = 0; i < len; i++) {
z = nums[i];
if (i > 0 && z == nums[i - 1])// avoid duplicate
continue;
if (z + 3 * max < target) // z is too small
continue;
if (4 * z > target) // z is too large
break;
if (4 * z == target) { // z is the boundary
if (i + 3 < len && nums[i + 3] == z)
res.add(Arrays.asList(z, z, z, z));
break;
}
threeSumForFourSum(nums, target - z, i + 1, len - 1, res, z);
}
进入3个数相加的同时,需要对target进行更新。
for (i = low; i < high - 1; i++) {
z = nums[i];
if (i > low && z == nums[i - 1]) // avoid duplicate
continue;
if (z + 2 * max < target) // z is too small
continue;
if (3 * z > target) // z is too large
break;
if (3 * z == target) { // z is the boundary
if (i + 1 < high && nums[i + 2] == z)
fourSumList.add(Arrays.asList(z1, z, z, z));
break;
}
twoSumForFourSum(nums, target - z, i + 1, high, fourSumList, z1, z);
}
进入两个数相加时,问题得到进一步简化。
int i = low, j = high, sum, x;
while (i < j) {
sum = nums[i] + nums[j];
if (sum == target) {
fourSumList.add(Arrays.asList(z1, z2, nums[i], nums[j])); x = nums[i];
while (++i < j && x == nums[i]) // avoid duplicate
;
x = nums[j];
while (i < --j && x == nums[j]) // avoid duplicate
;
}
if (sum < target)
i++;
if (sum > target)
j--;
}
参考代码:
package leetcode_50; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; /***
*
* @author pengfei_zheng
* 四个数加法等于target
*/
public class Solution18 {
public List<List<Integer>> fourSum(int[] nums, int target) {
ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
int len = nums.length;
if (nums == null || len < 4) //不足4个元素
return res; Arrays.sort(nums);//排序 int max = nums[len - 1];
if (4 * nums[0] > target || 4 * max < target)//4个最小值之和超过target或者4个最大值之和小于target
return res; int i, z;
for (i = 0; i < len; i++) {
z = nums[i];
if (i > 0 && z == nums[i - 1])// avoid duplicate
continue;
if (z + 3 * max < target) // z is too small
continue;
if (4 * z > target) // z is too large
break;
if (4 * z == target) { // z is the boundary
if (i + 3 < len && nums[i + 3] == z)
res.add(Arrays.asList(z, z, z, z));
break;
} threeSumForFourSum(nums, target - z, i + 1, len - 1, res, z);
} return res;
} public void threeSumForFourSum(int[] nums, int target, int low, int high, ArrayList<List<Integer>> fourSumList,
int z1) {
if (low + 1 >= high)
return; int max = nums[high];
if (3 * nums[low] > target || 3 * max < target)
return; int i, z;
for (i = low; i < high - 1; i++) {
z = nums[i];
if (i > low && z == nums[i - 1]) // avoid duplicate
continue;
if (z + 2 * max < target) // z is too small
continue; if (3 * z > target) // z is too large
break; if (3 * z == target) { // z is the boundary
if (i + 1 < high && nums[i + 2] == z)
fourSumList.add(Arrays.asList(z1, z, z, z));
break;
} twoSumForFourSum(nums, target - z, i + 1, high, fourSumList, z1, z);
} } public void twoSumForFourSum(int[] nums, int target, int low, int high, ArrayList<List<Integer>> fourSumList,
int z1, int z2) { if (low >= high)
return; if (2 * nums[low] > target || 2 * nums[high] < target)
return; int i = low, j = high, sum, x;
while (i < j) {
sum = nums[i] + nums[j];
if (sum == target) {
fourSumList.add(Arrays.asList(z1, z2, nums[i], nums[j])); x = nums[i];
while (++i < j && x == nums[i]) // avoid duplicate
;
x = nums[j];
while (i < --j && x == nums[j]) // avoid duplicate
;
}
if (sum < target)
i++;
if (sum > target)
j--;
}
return;
}
}
Full Code
LeetCode 18 4Sum (4个数字之和等于target)的更多相关文章
- LeetCode 18. 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 ...
- [LeetCode] 454. 4Sum II 四数之和II
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such t ...
- [LeetCode] 18. 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 ...
- LeetCode——18. 4Sum
一.题目链接:https://leetcode.com/problems/4sum/ 二.题目大意: 给定一个数组A和一个目标值target,要求从数组A中找出4个数来使之构成一个4元祖,使得这四个数 ...
- 18 4Sum(寻找四个数之和为指定数的集合Medium)
题目意思:给一个乱序数组,在里面寻找三个数之和为target的所有情况,这些情况不能重复,增序排列 思路:采用3Sum的做法 ps:有见一种用hash的,存任意两个元素的和,然后变成3sum问题,需要 ...
- leetcode 18 4Sum JAVA
题目 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出 ...
- [leetcode]18. 4Sum四数之和
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums s ...
- 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 ...
- [LeetCode] 18. 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 ...
随机推荐
- Java常用系统变量收集
public static void main(String[] args) { System.out.println("java版本号:" + System.getPropert ...
- Php反转字符串函数
From: http://blog.csdn.net/happy664618843/article/details/5861138
- SpringBoot和SpringCloud配置
1.基本配置 #项目名称(访问路径) server.context-path=/manager #端口 server.port=8764 #session过期时间 server.sessionTime ...
- Android Material Design控件学习(三)——使用TextInputLayout实现酷市场登录效果
前言 前两次,我们学习了 Android Material Design控件学习(一)--TabLayout的用法 Android Material Design控件学习(二)--Navigation ...
- 手机端网页使用html5地理定位获取位置失败的解决办法
网上有很多关于html5 geolocation 获取地理定位的方法,我试了下,只有在IE edge浏览器可以成功获取到,在chrome,firefox,手机端的safari,QQ浏览器,微信浏览器, ...
- javascript报错集锦
1.JS 异常之 missing ) after argument list 错误释疑报错原因:不是字符串就输出啦
- datetimerangepicker配置及默认时间段展示
<script type="text/javascript"> $(document).ready(function (){ //时间插件 $('#reportrang ...
- 【QT】Cannot find file: untitled.pro,项目路径不要包含中文。
Cannot find file: D:\文件及下载相关\文档\untitled\untitled.pro. 17:01:45: 进程"D:\Englishpath\QT5.9.3\5.9. ...
- Thinkphp 模板中使用自定义函数的方法
1.number_format {$number|number_format=2} 千分位,保留两位小数 2.round {$number|round=2} 四舍五入保留两位小数
- SQL 语句判断记录是否存在(最简洁简单性能最优)
今天查了下,发现网上的没有一个sql语句写的好的. 判断记录是否存在,要不是语句不够简洁,要不就是性能有很大问题. 我进行了优化后,最简洁简单性能最优的的sql语句,用来判断表中的记录是否存在: se ...