参考18. 四数之和。
题目
给你一个由 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
你可以按 任意顺序 返回答案 。
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
解题思路
-
排序+双指针:直接枚举时间复杂度为
O(n^4)
,排序之后可以使用双指针减少一维循环遍历复杂度。
排序+双指针
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
//先排序
Arrays.sort(nums);
int n = nums.length;
List<List<Integer>> ans = new ArrayList<>();
//枚举ab
for(int i = 0; i < n-3; i++){
//防止重复1
if(i>0 && nums[i] == nums[i-1]) continue;
for(int j = i+1; j < n-2; j++){
//防止重复2
if(j > i+1 && nums[j] == nums[j-1]) continue;
//双指针cd
int k = j+1,l = n-1;
while(k < l) {
//有个用例溢出需要用long接收
long sum = (long)nums[i]+nums[j]+nums[k]+nums[l];
if(sum == target) {
ans.add(Arrays.asList(nums[i], nums[j], nums[k], nums[l]));
k++;
l--;
//防止重复34
while(k < l && nums[k] == nums[k-1])k++;
while(k < l && nums[l] == nums[l+1])l--;
}
else if(sum < target) k++;
else l--;
}
}
}
return ans;
}
}
复杂度分析
- 时间复杂度:
O(n^3)
,n
为数组长度,排序为O(nlogn)
,总的时间复杂度=T(nlogn+n^3)=O(n^3)
。 - 空间复杂度:
O(nlogn)
,为排序的空间复杂度。
网友评论