和3Sum一个思路,只是多一层循环来确定第2个数,之后还是用双指针找第3、4个数
2Sum一直到kSum都使用这样的套路解题
/**
* 自己的代码
*/
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
int length = nums.length;
Arrays.sort(nums);
for (int i = 0; i < length - 3; i++) {
if (nums[i] * 4 > target) return ans; // 第一个数乘以4大于target,则后面不可能找到符合条件的4个数
if (i > 0 && nums[i] == nums[i - 1]) continue;
for (int j = i + 1; j < length - 2; j++) {
if (nums[i] + nums[j] * 3 > target) break; // 注意这里不能直接return,因为之后的外围循环有可能出现更小的nums[i] + nums[j]组合
if (j > i + 1 && nums[j] == nums[j - 1]) continue;
int start = j + 1, end = length - 1;
while (start < end) {
int sum = nums[i] + nums[j] + nums[start] + nums[end];
if (sum == target) {
ans.add(Arrays.asList(nums[i], nums[j], nums[start], nums[end]));
start++;
end--;
while (start < end && nums[start] == nums[start - 1]) start++;
while (start < end && nums[end] == nums[end + 1]) end--;
} else if (sum > target) {
end--;
while (start < end && nums[end] == nums[end + 1]) end--;
} else {
start++;
while (start < end && nums[start] == nums[start - 1]) start++;
}
}
}
}
return ans;
}
}
/**
* 另一种写法,一样的思路,只是将循环start++和end--的代码提到前面,重复的代码减少了
*/
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
int length = nums.length;
Arrays.sort(nums);
for (int i = 0; i < length - 3; i++) {
if (nums[i] * 4 > target)
return ans;
if (i > 0 && nums[i] == nums[i - 1])
continue;
for (int j = i + 1; j < length - 2; j++) {
if (nums[i] + nums[j] * 3 > target)
break;
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
int start = j + 1, end = length - 1;
while (start < end) {
if (start > j + 1 && nums[start] == nums[start - 1]) {
start++;
continue;
}
if (end < length - 1 && nums[end] == nums[end + 1]) {
end--;
continue;
}
int sum = nums[i] + nums[j] + nums[start] + nums[end];
if (sum == target) {
ans.add(Arrays.asList(nums[i], nums[j], nums[start], nums[end]));
start++;
end--;
} else if (sum > target) {
end--;
} else {
start++;
}
}
}
}
return ans;
}
}