【leetcode】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
你可以按 任意顺序 返回答案 。
示例 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]]
题目链接:18. 四数之和
解答
解答四数之和和解答三数之和的思路是一样的。
三数之和的暴力解法是三层for循环,然后使用双指针将两层for循环变成一层。所以三数之和的双指针解法时间复杂度是O(n^2)。
四数之和的暴力解法是四层for循环,然后使用双指针将两层for循环变成一层。所以四数之和的双指针解法的时间复杂度是O(n^3)。
三数之和解答:【leetcode】 15. 三数之和
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
if (nums.length < 4) {
return result;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 3; i++) {
// 去重1
if (i != 0 && nums[i - 1] == nums[i]) {
continue;
}
for (int j = i + 1; j < nums.length - 2; j++) {
// 去重2
if (j != i + 1 && nums[j - 1] == nums[j]) {
continue;
}
int left = j + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[left]);
list.add(nums[right]);
result.add(list);
// 去重3
while(left < right && nums[left] == nums[left + 1]) {
left++;
}
while(left < right && nums[right] == nums[right - 1]) {
right--;
}
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
}
return result;
}