题目链接
https://leetcode.cn/problems/4sum/
题目描述
题解一(Java)
作者:@仲景
思路和三数之和是一样的,排序+双指针,可以将本来O(n ^ 4)的时间复杂度降低到O(n ^ 3)
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
// 获取数组长度
int len = nums.length;
// 结果集
List<List<Integer>> res = new ArrayList<>();
// 对nums排序
Arrays.sort(nums);
// 遍历a
for (int a = 0; a < len; a++) {
// a剪枝
if (nums[a] > target && nums[a] >= 0) {
break;
}
// a去重
if (a > 0 && nums[a - 1] == nums[a]) {
continue;
}
// 遍历b
for (int b = a + 1; b < len; b++) {
// b剪枝
if (nums[a] + nums[b] > target && nums[a] + nums[b] >= 0) {
break;
}
// b去重
if (b > a + 1 && nums[b - 1] == nums[b]) {
continue;
}
// 双指针c,d
int c = b + 1;
int d = len - 1;
while (c < d) {
if ((long) nums[a] + nums[b] + nums[c] + nums[d] < target) {
c++;
} else if ((long) nums[a] + nums[b] + nums[c] + nums[d] > target) {
d--;
} else {
res.add(Arrays.asList(nums[a], nums[b], nums[c], nums[d]));
c++;
d--;
while (c < d && nums[c - 1] == nums[c]) {
c++;
}
while (c < d && nums[d + 1] == nums[d]) {
d--;
}
}
}
}
}
return res;
}
}
题解二(Go)
作者:@仲景
func fourSum(nums []int, target int) [][]int {
/*
和三数之和套路一样,也要求不重复
*/
len := len(nums)
res := make([][]int, 0)
sort.Ints(nums)
for a := 0; a < len-3; a++ {
// 去重:如果a和上一次的a相同,直接跳过
// 剪枝:如果nums[a]已经比target大,而且nums[a]>=0,那么无论怎么加,后面都不可能存在答案
if a > 0 && nums[a] == nums[a-1] || nums[a] > target && nums[a] >= 0 {
continue
}
for b := a + 1; b < len-2; b++ {
// 去重:如果b和上一次的b相同,直接跳过
// 剪枝:如果nums[a]+nums[b]已经比target大,而且和大于等于0,后面的至少和a、b一样,所以后面不存在答案
if b > a+1 && nums[b] == nums[b-1] || nums[a]+nums[b] > target && nums[a]+nums[b] >= 0 {
continue
}
for left, right := b+1, len-1; left < right; {
if sum := nums[a] + nums[b] + nums[left] + nums[right]; sum == target {
res = append(res, []int{nums[a], nums[b], nums[left], nums[right]})
// 对left去重
for left++; left < right && nums[left] == nums[left-1]; left++ {
}
// 对right去重
for right--; left < right && nums[right] == nums[right+1]; right-- {
}
} else if sum > target {
right--
} else {
left++
}
}
}
}
return res
}