题目描述:
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组
[nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):0 <= a, b, c, d < n a、b、c 和 d 互不相同 nums[a] + nums[b] + nums[c] +
nums[d] == target 你可以按 任意顺序 返回答案 。示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]] 示例 2:输入:nums = [2,2,2,2,2], target = 8 输出:[[2,2,2,2]]
解法一:双指针加排序:
与三数之和解法类似:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> ans=new ArrayList<>();
for(int i=0;i<nums.length;i++)
{
if(i>0&&nums[i]==nums[i-1])
{
continue;
}
for(int k=i+1;k<nums.length;k++)
{
if(k>i+1&&nums[k]==nums[k-1])
{
continue;
}
int l=k+1;
int r=nums.length-1;
while(l<r)
{
int sum=nums[i]+nums[k]+nums[l]+nums[r];
if(sum<target)
{
l++;
}else if(sum>target)
{
r--;
}else
{
ans.add(Arrays.asList(nums[i],nums[k],nums[l],nums[r]));
while(l<r&&nums[r]==nums[r-1])
{
r--;
}
while(l<r&&nums[l]==nums[l+1])
{
l++;
}
l++;
r--;
}
}
}
}
return ans;
}
}
解法二:求n数之和,递归+双指针+排序:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
return nSum(nums, target, 4);
}
/*
** n数之和
** @param number 要求几个数
*/
public static List<List<Integer>> nSum(int[] nums, int target, int number) {
if (nums.length < number) return new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
if (number > 2) {
// number大于2时,继续划分和递归,直到 number == 2
for (int i = 0; i < nums.length; i++) {
// 递归,数组划分、目标值target更新、number减一
List<List<Integer>> deeperResult = nSum(Arrays.copyOfRange(nums, i + 1, nums.length), target - nums[i], number - 1);
// 收集下层递归的返回值并处理
if (deeperResult.size() > 0) {
for (List<Integer> tempResult : deeperResult) {
tempResult.add(nums[i]);
// 去重后添加到result
if (!result.contains(tempResult)) {
result.add(tempResult);
}
}
}
}
} else {
// number == 2 时变为两数之和
int i = 0, j = nums.length - 1;
while (i < j) {
if (nums[i] + nums[j] < target) {
i++;
} else if (nums[i] + nums[j] > target) {
j--;
} else {
List<Integer> tempResult = new ArrayList<>(Arrays.asList(nums[i], nums[j]));
if (!result.contains(tempResult)) {
result.add(tempResult);
}
i++;
j--;
}
}
}
return result;
}
}