原题网址:https://leetcode.com/problems/3sum/
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:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- 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 {
private Set<String> founded = new HashSet<>();
private String arrayToString(int[] nums) {
String str = "[";
for(int i=0; i<nums.length; i++) {
if (i>0) str += ", ";
str += nums[i];
}
str += "]";
return str;
}
private int[] sort(int[] nums, int from, int to) {
if (from > to || from < 0 || to >= nums.length) return new int[0];
int[] result = new int[to-from+1];
if (from == to) {
result[0] = nums[from];
// System.out.printf("merge sort, before=%s, after=%s, from %d to %d\n", arrayToString(nums), arrayToString(result), from, to);
return result;
}
int mid = (from + to) / 2;
int[] s1 = sort(nums, from, mid);
int[] s2 = sort(nums, mid+1, to);
int i = 0, j = 0;
int pos = 0;
while (i < s1.length || j < s2.length) {
if (i >= s1.length) {
result[pos++] = s2[j++];
} else if (j >= s2.length) {
result[pos++] = s1[i++];
} else if (s1[i] <= s2[j]) {
result[pos++] = s1[i++];
} else {
result[pos++] = s2[j++];
}
}
// System.out.printf("merge sort, before=%s, after=%s, from %d to %d\n", arrayToString(nums), arrayToString(result), from, to);
return result;
}
private List<int[]> twoSum(int[] nums, int sum) {
// System.out.printf("nums=%s, sums=%d\n", arrayToString(nums), sum);
int i=0, j=nums.length-1;
List<int[]> result = new ArrayList<>();
while (i < j) {
if (nums[i] + nums[j] < sum) {
i ++;
} else if (nums[i] + nums[j] > sum) {
j --;
} else {
for(int k = j; k > i; k --) {
if (nums[i] + nums[k] == sum) {
int[] pair = new int[2];
pair[0] = nums[i];
pair[1] = nums[k];
// System.out.println("nums=" + arrayToString(nums));
// System.out.printf("i=%d, k=%d\n", i, k);
// System.out.println("pair=" + arrayToString(pair));
result.add(pair);
break;
} else {
break;
}
}
i ++;
}
}
return result;
}
public List<List<Integer>> threeSum(int[] nums) {
int[] sorted = sort(nums, 0, nums.length - 1);
// System.out.println("sorted=" + arrayToString(sorted));
List<List<Integer>> result = new ArrayList<>();
for(int i = 0; i < sorted.length - 2; i ++) {
while (0 < i && i < sorted.length - 1 && sorted[i] == sorted[i-1]) i++;
if (i == sorted.length) break;
int[] twos = new int[sorted.length - i - 1];
for(int j = i + 1; j < sorted.length; j ++ ) twos[j-i-1] = sorted[j];
List<int[]> pairs = twoSum(twos, -sorted[i]);
for(int k = 0; k < pairs.size(); k ++) {
List<Integer> threes = new ArrayList<>();
threes.add(sorted[i]);
threes.add(pairs.get(k)[0]);
threes.add(pairs.get(k)[1]);
String s = threes.toString();
if (this.founded.contains(s)) continue;
result.add(threes);
this.founded.add(s);
}
}
return result;
}
}
另一种实现:
public class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> results = new ArrayList<>();
for(int i=0; i<nums.length-2; i++) {
if (i>0 && nums[i]==nums[i-1]) continue;
int j=i+1, k=nums.length-1;
while (j<k) {
int sum = nums[i] + nums[j] + nums[k];
if (sum < 0) {
j ++;
} else if (sum > 0) {
k --;
} else {
Integer[] result = new Integer[3];
result[0] = nums[i];
result[1] = nums[j];
result[2] = nums[k];
results.add(Arrays.asList(result));
j ++;
k --;
}
while (j>i+1 && j<k && nums[j]==nums[j-1]) j++;
while (k<nums.length-1 && j<k && nums[k]==nums[k+1]) k--;
}
}
return results;
}
}

本文详细介绍了如何通过两数之和的思路解决LeetCode中的三数之和问题,并提供了两种不同的实现方法。文章还强调了算法优化的重要性,包括去重和排序,以确保找到所有独特的三元组。
&spm=1001.2101.3001.5002&articleId=51450504&d=1&t=3&u=5b5899f1652e40a0bb8e79d04d0d5657)
379

被折叠的 条评论
为什么被折叠?



