↑点击上面"算法半岛"
关注"算法半岛"第一时间接收最新文章
> 题目:18. 四数之和
> 难度:中等
> 分类:数组
> 解决方案:双指针
今天我们学习第18题四数之和,这是一道中等题。像这样数组的题目经常作为面试题来考察面试者算法能力和写代码能力,因此最好能手写出该题。下面我们看看这道题的题目描述。
给定一个包含 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]
]
在前面,我们做过LeetCode-1 两数之和与LeetCode-15 三数之和,这个题目是求四数之和,其基本思路和三数之和差不多,只是在三数之和的基础上增加一个 for
循环。具体求解过程详见LeetCode-15 三数之和。 java
代码如下所示:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(nums == null && nums.length < 4)
return res;
// 对数组排序
Arrays.sort(nums);
// 固定第一个数
for(int i=0; i<nums.length-3; ++i){
if(i!=0 && nums[i] == nums[i-1])
continue;
if(nums[i+1]>0 && nums[i] >= target)
return res;
// 固定第二个数
for(int j=i+1; j<nums.length-2; ++j){
if((j != i + 1) && nums[j] == nums[j-1])
continue;
// 使用左右指针进行查找
int left = j+1, right = nums.length-1;
while(left < right){
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if(sum == target){
ArrayList<Integer> tmp = new ArrayList<Integer>();
tmp.add(nums[i]);
tmp.add(nums[j]);
tmp.add(nums[left]);
tmp.add(nums[right]);
res.add(tmp);
++left;
--right;
while(left<right && nums[left] == nums[left-1])
++left;
while(left<right && nums[right] == nums[right+1])
--right;
}else if(sum > target)
--right;
else
++left;
}
}
}
return res;
}
}
LeetCode-18 四数之和 :https://github.com/JacobLei/leetcode/blob/master/src/main/java/A18_4Sum.java
四数之和:https://leetcode-cn.com/problems/4sum/