Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
给出一个数组,找出所有和为0的三个元素
思路:
可以找出一个元素,剩下的转化为2Sum,但是直接2Sum会TLE
而且有重复的case
所以先把数组排序,容易去重
转化为2Sum时,用两个pointer, 一个从左到右,一个从右到左
和满足0时,去重复元素后left++, right–,以找到所有case
不满足0时,如果<0, left++, 反之right –
//27ms
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (nums == null || nums.length < 3) {
return result;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left+1]) left++;
while (left < right && nums[right] == nums[right-1]) right--;
left ++;
right --;
} else if (sum < 0) {
left ++;
} else {
right --;
}
}
}
return result;
}
16 . 3 Sum Closest
Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Example:
Given array nums = [-1, 2, 1, -4], and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
给出一个数组,找出其中3个元素的和,距离target最近。只有一个解
思路:
沿用上面3Sum的方法,只是不需要找出所有的解,遇到Sum=target即返回
同时还是把3Sum排序后转为2Sum,用双指针
//5ms
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int closest = nums[0] + nums[1] + nums[2];
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (Math.abs(target - closest) > Math.abs(target - sum)) {
closest = sum;
}
if (sum == target) {
return target;
} else if (sum < target) {
left ++;
} else {
right --;
}
}
}
return closest;
}
18 . 4Sum
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
The solution set must not contain duplicate quadruplets.
Example:
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
给出一个数组,找出4个元素的和=target,找出所有的解
思路:
仍然是先排序,以去重
找出一个元素,剩下的部分转为3Sum
4Sum的部分要检查重复元素,3Sum中也是检查重复元素
同时左边4个元素的和>target时,证明最小元素的和都不满足,跳出循环
右边4个元素的和<target时,证明最大元素的都不满足,跳出循环
//3ms..
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (nums == null || nums.length < 4) {
return result;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 3; i++) {
if (i > 0 && nums[i] == nums[i-1]) continue;
//most left & most right elements check..
if (nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target) break;
if (nums[nums.length-1] + nums[nums.length-2] + nums[nums.length-3]
+ nums[nums.length-4] < target) break;
//to 3Sum..
for (int next = i + 1; next < nums.length - 2; next ++) {
if (next > i+1 && nums[next] == nums[next - 1]) continue;
int left = next + 1;
int right = nums.length - 1;
if (nums[i] + nums[next] + nums[next+1] + nums[next+2] > target) break;
if (nums[i] + nums[right] + nums[right-1] + nums[right-2] < target) break;
//similar to 3Sum..
while (left < right) {
int sum = nums[i] + nums[next] + nums[left] + nums[right];
if (sum == target) {
result.add(Arrays.asList(nums[i], nums[next], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right-1]) right--;
left ++;
right --;
} else if (sum < target) {
left ++;
} else {
right --;
}
}
}
}
return result;
}