编程语言:Java
题目链接:https://leetcode-cn.com/problems/4sum/
题解:其他都简单,主要是剪枝,为了让大家能看懂,注释写的满满的。
难度:Medium
结果:以后就不放图片了,好麻烦
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if (nums == null || nums.length < 4) {
return res;
}
Arrays.sort(nums);
int len = nums.length;
for (int i = 0; i < len - 3; i++) {
//如果此时最小的组合都大于了target,就退出
if (nums[i] + nums[i + 1] > target - nums[i + 2] - nums[i + 3]) {
break;
}
//如果此时最大的组合都小于了target,就前进
if (nums[i] + nums[len - 3] < target - nums[len - 2] - nums[len - 1]) {
continue;
}
for (int j = i + 1; j < len - 2; j++) {
//此处的两个剪枝道理同上
if (nums[i] + nums[j] > target - nums[j + 1] - nums[j + 2]) {
break;
}
if (nums[i] + nums[j] < target - nums[len - 2] - nums[len - 1]) {
continue;
}
int l = j + 1, r = len - 1;
while (l < r) {
if (nums[i] + nums[j] == target - nums[l] - nums[r]) {
List<Integer> list = new ArrayList(Arrays.asList(nums[i],nums[j],nums[l],nums[r]));
if (!res.contains(list))
res.add(list);
//去除第三个数和第四个数的重复部分
// 下面这几段代码总体的效果可以理解为:
// ①将l移动到了重复部分的右边那个数,即[-1,0,0,0,2,3,4]中的2;
// ②将r移动到了重复部分的左边那个数,即[-1,0,0,0,2,3,4]中的-1。
// *这个例子只是说明移动到了哪个位置
while (l < r && nums[l] == nums[l + 1]) {
l++;
}
while (l < r && nums[r] == nums[r - 1]) {
r--;
}
l++;
r--;
} else if (nums[i] + nums[j] < target - nums[l] - nums[r]) {
l++;
} else {
r--;
}
}
}
}
return res;
}
}