题目
给你一个由 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
你可以按 任意顺序 返回答案 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
int n= nums.length;
Arrays.sort(nums);
return nSum(nums,4,0,target);
}
List<List<Integer>> nSum(int[] nums,int n, int start,int target){//nsum
int len =nums.length;
List<List<Integer>> ans = new ArrayList<>();
// 至少是 2Sum,且数组大小不应该小于 n
if (n<2||len<n) return ans;
if (n==2){//twoSum问题
//双指针
int l=start,r=len-1;
while (l<r){
int sum =nums[l]+nums[r];
int left=nums[l],right=nums[r];
if (sum>target){
while (r>l&&nums[r]==right){
r--;
}
}else if (sum<target){
while (l<r&&nums[l]==left)
l++;
}else {
List<Integer> temp = new ArrayList<Integer>();
temp.add(left);
temp.add(right);
ans.add(new ArrayList<>(temp));
while (l<r&&nums[l]==left) l++;//防止重复
while (l<r&&nums[r]==right) r--;
}
}
}else {// n > 2 时,递归计算 (n-1)Sum 的结果
for (int i = start; i <len ; i++) {
List<List<Integer>> sub=nSum(nums,n-1,i+1,target-nums[i]);
for (List<Integer> arr:sub
) {
arr.add(nums[i]);//将子结果加上num[i]后添加如答案
ans.add(new ArrayList<>(arr));
}
while (i<len-1&& nums[i]==nums[i+1]) i++;//防止重复
}
}
return ans;
}
}
要点
- 4数和问题可以归类为nSum问题,我们通过声名nSum方法来进行计算
- 若n>2,则遍历num数组,将剩下看做n-1Sum这么一个子问题,最后合并
- 若n=2,则是twoSum问题,使用双指针法进行计算
- 注意在调用nSum方法之前先对num进行排序
- 注意不能重复计算,所以需要防止记录重复的list