与传统的3sum问题相比,如果任何三个元素的总和等于零,则查找所有三元组,我们可以使用任何重复项。 例如,对于输入数组[-2,-1,3,4],( - 2,-2,4)也是一种解决方案。 (-2是重复的,允许)。 我的解决方案是将每个元素分成3个副本,然后将修改后的元素视为传统的3sum问题。但是这种方法在最坏的情况下花费O(2n)空间。是否有可用的恒定空间解决方案?
答案 0 :(得分:0)
问题有点不清楚,因为您还没有发布您的实际实施。但是,假设standard O(n^2) implementation没有散列:
sort(S);
for i=0 to n-3 do
a = S[i];
start = i+1;
end = n-1;
while (start < end) do
b = S[start];
c = S[end];
if (a+b+c == 0) then
output a, b, c;
start = start + 1
end = end - 1
else if (a+b+c > 0) then
end = end - 1;
else
start = start + 1;
end
end
end
通过将变量start
初始化为i
而不是i+1
,您可以在解决方案中获得重复项。此外,如果允许最后三元组中的所有元素来自同一个数组元素,则另外将循环条件从while (start < end)
更改为while (start <= end)
。
答案 1 :(得分:0)
public static List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> resultList = new ArrayList();
int start1 = 0;
while (start1 <= nums.length - 1 - 2) {
int start2 = start1 + 1;
int end = nums.length - 1;
while (true) {
if (start2 >= end) {
break;
}
int result = nums[start1] + nums[start2] + nums[end];
if (result == 0) {
addToResponse(resultList, nums[start1], nums[start2], nums[end]);
do {
start2++;
} while (start2 < end && nums[start2] == nums[start2 - 1]);
do {
end--;
} while (end > start2 && nums[end] == nums[end + 1]);
} else if (result > 0) {
do {
end--;
} while (end > start2 && nums[end] == nums[end + 1]);
} else if (result < 0) {
do {
start2++;
} while (start2 < end && nums[start2] == nums[start2 - 1]);
}
}
do {
start1++;
}
while (nums[start1] == nums[start1 - 1] && start1 < nums.length-1);
}
return resultList;
}
private static void addToResponse(List<List<Integer>> result, int a, int b, int c) {
result.add(Arrays.asList(a, b, c));
}