给你一个由
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]]提示:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
java 解题及思路
package com.java.leetcode.hash;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 给你一个由 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]]
*
*
* 提示:
*
* 1 <= nums.length <= 200
* -109 <= nums[i] <= 109
* -109 <= target <= 109给你一个由 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]]
*
*
* 提示:
*
* 1 <= nums.length <= 200
* -109 <= nums[i] <= 109
* -109 <= target <= 109
*
*/
public class fourSumfourSum18 {
/**
*
* @param nums
* @param target
* @return
*/
public List<List<Integer>> fourSum(int[] nums, int target) {
/**
* 给定条件 a+b+c+d=target
* a,b,c,d index 各不相同
* 四元组 不重复
* 去重原则 可以借鉴 三数之和的解法
* a+b+c+d=target => (a+b)+c+d=target=> (a+b)+(c+d)=target=>(a+b)=target-(c+d)
* 因此 固定 a+b 使用双指针法获取 taget-(c+d)=(a+b);
* 依照上述思路:
*/
List<List<Integer>> list=new ArrayList<>();
//判空
if(nums==null||nums.length<4){
return list;
}
Arrays.sort(nums);
//元素 判别 上下边界 int 类型加和 越界导致 加和值相等
if((nums[0]>=0&&nums[0]>target)||(nums[nums.length-1]<=0&&nums[nums.length-1]<target)){
return list;
}
for(int i=0;i<nums.length-3;i++){
// 处理 a+b相同 时候的 a=b元素重复计入的问题 此时应该是 此时只计算第一个后面重复的去掉
if(i>0&&nums[i-1]==nums[i]){
continue;
}
for(int j=i+1;j<nums.length-2;j++){
// 对nums[j] 去重
if(j>i+1&&nums[j]==nums[j-1]){
continue;
}
int left =j+1;
int right=nums.length-1;
int t=nums[i]+nums[j];
while(left<right){
if(t+nums[left]+nums[right]<target){
left++;
}else if(t+nums[left]+nums[right]>target){
right--;
}else{
while(nums[left]==nums[left+1]&&left+1<right){
left++;
}
while(nums[right]==nums[right-1]&&right-1>left){
right--;
}
List<Integer>tmp=new ArrayList<>();
tmp.add(nums[i]);
tmp.add(nums[j]);
tmp.add(nums[left]);
tmp.add(nums[right]);
list.add(tmp);
left++;
right--;
}
}
}
}
return list;
}
}