package main.java.demo18;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FourSum {
private List<List<Integer>> result = new ArrayList<>();
private Boolean[][] booleans = new Boolean[201][201];
/**
* 解题思路: 先排序, 在双指针, 两层双指针, 这样写会出现一些问题, 比如输入{2,2,2,2,2} target = 8.
* 现在脑子有点混乱, 之后刷到类似题再回来解决, 下面方法使用简单的两层循环加双指针.
*
* @param nums
* @param target
* @return
*/
public List<List<Integer>> fourSum_1(int[] nums, int target) {
int n = nums.length;
Arrays.sort(nums);
for (int i = 0; i < 201; i++) {
for (int j = 0; j < 201; j++) {
booleans[i][j] = false;
}
}
recursion(0, n - 1, nums, target);
return result;
}
public void recursion(int outerLeft, int outerRight, int[] nums, int target) {
if (outerLeft >= outerRight) {
return;
}
int n = nums.length;
if (outerLeft > 0 && nums[outerLeft - 1] == nums[outerLeft]) {
if (booleans[outerLeft + 1][outerRight] == true) {
return;
}
recursion(outerLeft + 1, outerRight, nums, target);
booleans[outerLeft + 1][outerRight] = true;
}
if (outerRight < n - 2 && nums[outerRight + 1] == nums[outerRight]) {
if (booleans[outerLeft][outerRight - 1] == true) {
return;
}
recursion(outerLeft, outerRight - 1, nums, target);
booleans[outerLeft][outerRight - 1] = true;
}
int innerSum = target - nums[outerLeft] - nums[outerRight];
int innerLeft = outerLeft + 1;
int innerRight = outerRight - 1;
while (innerLeft < innerRight) {
if (innerLeft > outerLeft + 1 && nums[innerLeft - 1] == nums[innerLeft]) {
innerLeft++;
continue;
}
if (innerRight < outerRight - 1 && nums[innerRight + 1] == nums[innerRight]) {
innerRight--;
continue;
}
int val = innerSum - nums[innerLeft] - nums[innerRight];
if (val == 0) {
List<Integer> current = new ArrayList<>();
current.add(nums[outerLeft]);
current.add(nums[outerRight]);
current.add(nums[innerLeft]);
current.add(nums[innerRight]);
result.add(current);
innerLeft++;
innerRight--;
} else if (val > 0) {
innerLeft++;
} else {
innerRight--;
}
}
// -2,-1,0,0,1,2
if (booleans[outerLeft + 1][outerRight] == false) {
recursion(outerLeft + 1, outerRight, nums, target);
booleans[outerLeft + 1][outerRight] = true;
}
// while (outerLeft > 0 && nums[outerLeft - 1] == nums[outerLeft]) {
// outerLeft++;
// }
if (booleans[outerLeft][outerRight - 1] == false) {
recursion(outerLeft, outerRight - 1, nums, target);
booleans[outerLeft][outerRight - 1] = true;
}
}
public List<List<Integer>> fourSum_2(int[] nums, int target) {
int n = nums.length;
int sum;
int leftPoint;
int rightPoint;
Arrays.sort(nums);
for (int i = 0; i < n - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < n - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
sum = target - nums[i] - nums[j];
leftPoint = j + 1;
rightPoint = n - 1;
while (leftPoint < rightPoint) {
if (leftPoint > j + 1 && nums[leftPoint] == nums[leftPoint - 1]) {
leftPoint++;
continue;
}
if (rightPoint < n - 1 && nums[rightPoint] == nums[rightPoint + 1]) {
rightPoint--;
continue;
}
int val = sum - nums[leftPoint] - nums[rightPoint];
if (val == 0) {
List<Integer> current = new ArrayList<>();
current.add(nums[i]);
current.add(nums[j]);
current.add(nums[leftPoint]);
current.add(nums[rightPoint]);
result.add(current);
rightPoint--;
leftPoint++;
} else if (val < 0) {
rightPoint--;
} else {
leftPoint++;
}
}
}
}
return result;
}
@Test
public void formSumTest() {
// System.out.println(fourSum_1(new int[]{-3,-1,0,2,4,5}, 0));
// System.out.println(fourSum_2(new int[]{-2,-1,0,0,1,2}, 0));
System.out.println(fourSum_2(new int[]{2,2,2,2,2}, 8));
}
}
求和为给定值的四元组
最新推荐文章于 2022-07-15 18:30:44 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)