问题描述
给定一个有序数组arr,给定一个正数aim
- 返回累加和为aim的,所有不同二元组
- 返回累加和为aim的,所有不同三元组
条件一思路
双指针求解。
定义双指针L和R,应为数组是有序的那么必然存在单调性,规定 arr[L] + arr[R] 和为两者之和S,当 S > aim 时向左移动R,当 S 小于 aim 时,向右移动 R,当 S 等于 aim 时找到一个二元组。注意在 S 等于 aim 时,只有在 L 不等于 L-1 或者 R 不等 R+1 的情况下才收集答案,应为这种情况下收集到的答案是第一次遇到的二元组。
条件一代码
public static class Yuan {
public int first;
public int second;
public Yuan(int a, int b) {
first = a;
second = b;
}
}
public static List<Yuan> erYuan(int[] arr, int aim) {
if (arr == null || arr.length == 0) {
return null;
}
int n = arr.length;
List<Yuan> res = new ArrayList<>();
int L = 0;
int R = n - 1;
while (L < R) {
if (arr[L] + arr[R] < aim) {
L++;
} else if ((arr[L] + arr[R] > aim)) {
R--;
} else {
if (L == 0 || arr[L] != arr[L - 1]) {
res.add(new Yuan(arr[L++], arr[R]));
} else {
L++;
}
}
}
return res;
}
条件二思路
从头开始遍历每一个元素,当前位置为 i,记为三元组的第一个元素。把 aim-arr[i] 记为第一问的aim,求 i 之后的数组中包含二元组和为 aim-arr[i] 的解。
条件二代码
public static class SanYuan {
public int first;
public int second;
public int third;
public SanYuan(int a, int b, int c) {
first = a;
second = b;
third = c;
}
}
public static List<SanYuan> sanYuan(int[] arr, int aim) {
if (arr == null || arr.length == 0) {
return null;
}
int n = arr.length;
List<SanYuan> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
int L = i + 1;
int R = n - 1;
int temp = aim - arr[i];
while (L < R) {
if (arr[L] + arr[R] < temp) {
L++;
} else if (arr[L] + arr[R] > temp) {
R--;
} else {
if (L == 0 || arr[L] != arr[L - 1]) {
res.add(new SanYuan(arr[i], arr[L++], arr[R]));
} else {
L++;
}
}
}
}
return res;
}