题目描述
给定一个包含 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]
]
算法分析
排序 + 双指针
- 1、与三数之和操作类似,枚举每两个数,表示该数
nums[i]
和nums[j]
已被确定,在排序后的情况下,通过双指针l
,r
分别从左边l = i + 1
和右边n - 1
往中间靠拢,找到nums[i] + nums[j] + nums[l] + nums[r] == target
的所有符合条件的搭配 - 2、在找符合条件搭配的过程中,假设
sum = nums[i] + nums[j] + nums[l] + nums[r]
- 若
sum > target
,则r
往左走,使sum
变小 - 若
sum < target
,则l
往右走,使sum
变大 - 若
sum == target
,则表示找到了与nums[i]
搭配的组合nums[l]
和nums[r]
,存到ans
中
- 若
- 3、判重处理
- 确定好
nums[i]
时,l
需要从i + 1
开始 - 当
nums[i] == nums[i - 1]
,表示当前确定好的数与上一个一样,需要直接continue
- 当
nums[j] == nums[j - 1]
,表示当前确定好的数与上一个一样,需要直接continue
- 当找符合条件搭配时,即
sum == 0
,需要对相同的nums[l]
和nums[r]
进行判重出来
- 确定好
时间复杂度 $O(n^3)$
Java 代码
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
int n = nums.length;
Arrays.sort(nums);
for(int i = 0;i < n;i ++)
{
if(i != 0 && nums[i] == nums[i - 1]) continue;
for(int j = i + 1;j < n;j ++)
{
if(j != i + 1 && nums[j] == nums[j - 1]) continue;
int l = j + 1,r = n - 1;
while(l < r)
{
int sum = nums[i] + nums[j] + nums[l] + nums[r];
if(sum > target)
{
r --;
continue;
}
if(sum < target)
{
l ++;
continue;
}
ans.add(Arrays.asList(nums[i],nums[j],nums[l],nums[r]));
//去重处理
do{l ++;} while(l < r && nums[l] == nums[l - 1]);
do{r --;} while(l < r && nums[r] == nums[r + 1]);
}
}
}
return ans;
}
}
leetcode改了测试用例,现在需要用long来保存sum,否则会越界
2024考古,确实,擦
tql
超赞!
谢谢hh