每天一题LeetCode[第十六天]
4 Sum
Description:
Given an array S of n integers, are there elements a, b, c, and d in S 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.
For example, given array S = [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]
]
翻译:
给一串整型字符串数字,判断是否有这样的元素a b c d 满足 a+b+c+d=target? 给出target,找到所有满足条件的组合。
注意:组合必须没有重复。例子如上
解题过程:
这道题是在3 Sum的基础上,又增加了一个变量。 思路很简单,就是如何把4 sum->变成3 sum 就可以解决啦。 如何转换呢,就是先排序一下,然后遍历,每次去一个作为基础值 x,就可以把4变成3,target变成 target-基础值。
值得注意的是,一些细节,比如如果当前值 乘4小于target,那么 循环可以不用继续下去,还有很多,可以提高效率的判断,这方面做得没有top solution好。。还有一点是,记得要去重!!!参考Top Solution
Java代码:**
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
//如果为null或者长度还没到4
if (null == nums || nums.length < 4) {
return ans;
}
Arrays.sort(nums);
//如果最小都大于target 或者 最大都小于target 则直接返回
if (4 * nums[0] > target || 4 * nums[nums.length - 1] < target) {
return ans;
}
for (int i = 0; i < nums.length - 3; i++) {
int x = nums[i];
if (i > 0 && x == nums[i - 1]) {
continue;
}
//全部太大
if (4 * x > target) {
break;
}
//此次太小
if (x + 3 * nums[nums.length - 1] < target) {
continue;
}
if (4 * x == target && x == nums[i + 3]) {
ans.add(Arrays.asList(x, x, x, x));
i = i + 2;
continue;
}
threeSum(ans, target - x, nums, i + 1, nums.length, x);
}
return ans;
}
private void threeSum(List<List<Integer>> ans, int target, int[] nums, int start, int end, int x) {
if (start + 1 >= end) {
return;
}
if (3 * nums[start] > target || 3*nums[end]<target) {
return;
}
for (int i = start; i < nums.length - 2; i++) {
int x1 = nums[i];
//去重
if (i > start && x1 == nums[i - 1]) {
continue;
}
int tmpTarget = target - x1;
int low = i + 1, high = nums.length - 1;
//全部太大了
if (2 * nums[low] > tmpTarget) {
break;
}
//此次
if (2 * nums[high] < tmpTarget) {
continue;
}
//夹逼查找
while (low < high) {
int tmpSum = nums[low] + nums[high];
if (tmpSum < tmpTarget) {
low++;
} else if (tmpSum > tmpTarget) {
high--;
} else {
ans.add(Arrays.asList(x, x1, nums[low], nums[high]));
//去重
while (++low < high && nums[low - 1] == nums[low]) ;
while (--high > low && nums[high] == nums[high + 1]) ;
}
}
}
}
}
提高代码质量就是:积累精美的思路,优质的细节的过程。