【题目】Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
【Note】
1.Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
2.The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2)【代码】
public class Solution {
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (nums.length<3)
return result;
sort(nums, 0, nums.length-1);
// Arrays.sort(nums);
List<Integer> temp = new ArrayList<Integer>();
if (nums[0] + nums[1] + nums[2] > 0)
return result;
if (nums[0] + nums[1] + nums[2] == 0) {
temp.add(nums[0]);
temp.add(nums[1]);
temp.add(nums[2]);
result.add(temp);
return result;
}
int begin = 0, mid, end;
while (begin < nums.length-1) {
while (begin > 0 && begin < nums.length -1&& nums[begin] == nums[begin - 1])
begin++;
mid = begin + 1;
end = nums.length - 1;
while (mid < end) {
if (nums[begin] + nums[mid] + nums[end] == 0) {
List<Integer> temp1 = new ArrayList<Integer>();
temp1.add(nums[begin]);
temp1.add(nums[mid]);
temp1.add(nums[end]);
result.add(temp1);
mid++;
end--;
while (mid < end && nums[mid] == nums[mid - 1])
mid++;
while (end > mid && nums[end] == nums[end + 1])
end--;
} else if (nums[begin] + nums[mid] + nums[end] < 0) {
mid++;
while (mid < end && nums[mid] == nums[mid - 1])
mid++;
}
else {
end--;
while (end > mid && nums[end] == nums[end + 1])
end--;
}
}
begin++;
}
// HashSet h = new HashSet(result);
// result.clear();
// result.addAll(h);
return result;
}
public static int[] sort(int[] nums, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
sort(nums, low, mid);
sort(nums, mid + 1, high);
merge(nums, low, mid, high);
}
return nums;
}
public static void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;// 左指针
int j = mid + 1;// 右指针
int k = 0;
while (i <= mid && j <= high) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
while (i <= mid) {
temp[k++] = nums[i++];
}
while (j <= high) {
temp[k++] = nums[j++];
}
for (int k2 = 0; k2 < temp.length; k2++) {
nums[k2 + low] = temp[k2];
}
}
}
}
【算法思想】先对链表排序,也可以直接使用函数排序,再设前中后三个指针,前一个指针作为固定,中间指针最后一个指针从两端挪动,如果三个值和等于零,放入list里,如果小于零,中间指针后移,如果大于零,后面指针前移,直到找到所有的符合的值。
【总结】比较虐心的一道题,因为老是超时,后来上网查,发现必须将所有经过的相同的数据过滤掉,才能AC!