开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情
18. 四数之和:
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < na、b、c和d互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
样例 1:
输入:
nums = [1,0,-1,0,-2,2], target = 0
输出:
[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
样例 2:
输入:
nums = [2,2,2,2,2], target = 8
输出:
[[2,2,2,2]]
提示:
- 1 <= nums.length <= 200
- -109 <= nums[i] <= 109
- -109 <= target <= 109
原题传送门:
分析
- 面对这道算法题目,二当家的陷入了沉思。
- 第一反应就是暴力四层循环,但是据说会超时。
- 如果是两数之和,在知道第一个数的情况下,第二个数也就固定了;
- 四数之和在第一个数固定后,并不能固定第二个数,第三个数和第四个数,所以才需要四层循环。
- 然而如果我们把数组先排序一下,在确定了前两个数之后,后两个数就有了关系,一个数越大,另一个数就需要越小,可以合并成一次循环。
题解
rust
impl Solution {
pub fn four_sum(mut nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
let mut ans = Vec::new();
let n = nums.len();
if n < 4 {
return ans;
}
nums.sort();
for first in 0..n - 3 {
if first > 0 && nums[first] == nums[first - 1] {
continue;
}
if nums[first] as i64 + nums[first + 1] as i64 + nums[first + 2] as i64 + nums[first + 3] as i64 > target as i64 {
break;
}
if target as i64 > nums[first] as i64 + nums[n - 3] as i64 + nums[n - 2] as i64 + nums[n - 1] as i64 {
continue;
}
for second in first + 1..n - 2 {
if second > first + 1 && nums[second] == nums[second - 1] {
continue;
}
if nums[first] as i64 + nums[second] as i64 + nums[second + 1] as i64 + nums[second + 2] as i64 > target as i64 {
break;
}
if target as i64 > nums[first] as i64 + nums[second] as i64 + nums[n - 2] as i64 + nums[n - 1] as i64 {
continue;
}
let mut fourth = n - 1;
let t = target as i64 - nums[first] as i64 - nums[second] as i64;
for third in second + 1..n - 1 {
if third > second + 1 && nums[third] == nums[third - 1] {
continue;
}
while third < fourth && nums[third] as i64 + nums[fourth] as i64 > t {
fourth -= 1;
}
if third == fourth {
break;
}
if nums[third] as i64 + nums[fourth] as i64 == t {
ans.push(vec![nums[first], nums[second], nums[third], nums[fourth]]);
}
}
}
}
return ans;
}
}
go
func fourSum(nums []int, target int) [][]int {
n := len(nums)
if n < 4 {
return nil
}
sort.Ints(nums)
var ans [][]int
for first := 0; first < n-3; first++ {
if first > 0 && nums[first] == nums[first-1] {
continue
}
if nums[first]+nums[first+1]+nums[first+2]+nums[first+3] > target {
break
}
if nums[first]+nums[n-3]+nums[n-2]+nums[n-1] < target {
continue
}
for second := first + 1; second < n-2; second++ {
if second > first+1 && nums[second] == nums[second-1] {
continue
}
if nums[first]+nums[second]+nums[second+1]+nums[second+2] > target {
break
}
if nums[first]+nums[second]+nums[n-2]+nums[n-1] < target {
continue
}
fourth := n - 1
t := target - nums[first] - nums[second]
for third := second + 1; third < n-1; third++ {
if third > second+1 && nums[third] == nums[third-1] {
continue
}
for third < fourth && nums[third]+nums[fourth] > t {
fourth -= 1
}
if third == fourth {
break
}
if nums[third]+nums[fourth] == t {
ans = append(ans, []int{nums[first], nums[second], nums[third], nums[fourth]})
}
}
}
}
return ans
}
c++
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
int n = nums.size();
if (n < 4) {
return ans;
}
sort(nums.begin(), nums.end());
for (int first = 0; first < n - 3; ++first) {
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
if ((long) nums[first] + nums[first + 1] + nums[first + 2] + nums[first + 3] > target) {
break;
}
if ((long) nums[first] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) {
continue;
}
for (int second = first + 1; second < n - 2; ++second) {
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
if ((long) nums[first] + nums[second] + nums[second + 1] + nums[second + 2] > target) {
break;
}
if ((long) nums[first] + nums[second] + nums[n - 2] + nums[n - 1] < target) {
continue;
}
int fourth = n - 1;
int t = target - nums[first] - nums[second];
for (int third = second + 1; third < n - 1; ++third) {
if (third > second + 1 && nums[third] == nums[third - 1]) {
continue;
}
while (third < fourth && nums[third] + nums[fourth] > t) {
fourth -= 1;
}
if (third == fourth) {
break;
}
if (nums[third] + nums[fourth] == t) {
ans.push_back({nums[first], nums[second], nums[third], nums[fourth]});
}
}
}
}
return ans;
}
};
java
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
int n = nums.length;
if (n < 4) {
return ans;
}
Arrays.sort(nums);
for (int first = 0; first < n - 3; ++first) {
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
if ((long) nums[first] + nums[first + 1] + nums[first + 2] + nums[first + 3] > target) {
break;
}
if ((long) nums[first] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) {
continue;
}
for (int second = first + 1; second < n - 2; ++second) {
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
if ((long) nums[first] + nums[second] + nums[second + 1] + nums[second + 2] > target) {
break;
}
if ((long) nums[first] + nums[second] + nums[n - 2] + nums[n - 1] < target) {
continue;
}
int fourth = n - 1;
int t = target - nums[first] - nums[second];
for (int third = second + 1; third < n - 1; ++third) {
if (third > second + 1 && nums[third] == nums[third - 1]) {
continue;
}
while (third < fourth && nums[third] + nums[fourth] > t) {
fourth -= 1;
}
if (third == fourth) {
break;
}
if (nums[third] + nums[fourth] == t) {
ans.add(Arrays.asList(nums[first], nums[second], nums[third], nums[fourth]));
}
}
}
}
return ans;
}
}
python
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
ans = list()
n = len(nums)
if n < 4:
return ans
nums.sort()
for first in range(n - 3):
if first > 0 and nums[first] == nums[first - 1]:
continue
if nums[first] + nums[first + 1] + nums[first + 2] + nums[first + 3] > target:
break
if nums[first] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target:
continue
for second in range(first + 1, n - 2):
if second > first + 1 and nums[second] == nums[second - 1]:
continue
if nums[first] + nums[second] + nums[second + 1] + nums[second + 2] > target:
break
if nums[first] + nums[second] + nums[n - 2] + nums[n - 1] < target:
continue
fourth = n - 1
t = target - nums[first] - nums[second]
for third in range(second + 1, n - 1):
if third > second + 1 and nums[third] == nums[third - 1]:
continue
while third < fourth and nums[third] + nums[fourth] > t:
fourth -= 1
if third == fourth:
break
if nums[third] + nums[fourth] == t:
ans.append([nums[first], nums[second], nums[third], nums[fourth]])
return ans
非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://juejin.cn/user/2771185768884824/posts 博客原创~
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情