n数之和题目要类比——LeetCode题目18:四数之和

时间:2022-07-23
本文章向大家介绍n数之和题目要类比——LeetCode题目18:四数之和,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

原题描述

+

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:答案中不可以包含重复的四元组。

示例

输入:nums = [1,0,-1,0,-2,2], target=0

输出:[[-1,0,0,1],[-2,-1,1,2],[-2,0,0,2]]

原题链接:https://leetcode-cn.com/problems/4sum

思路解析

+

LeetCode中n数之和相关的题目有很多,除了两数之和以外,几乎都是同一种思路,所以弄懂其中一道题就可以刷其他题目了。

我们再回顾一下三数之和的基本思路:

1. 先将数组按照升序排序;

2. 以当前位置 作为三数之中的第一个数字(最小的数字),寻找他的其他两个伙伴,这两个伙伴一定处于 之后。我们使用两个可移动的指针 和 分别指向 和最后一一位数字,因为数组按升序排序,所以有两个基本事实:右移 会使和增大,左移 会使和减小。

到了四数之和,思路没有任何区别,只是又多了一层外循环而已。

关于排序+双指针的具体方法解析,我建议你直接看下面两篇文章。

LeetCode题目15:三数之和

这题是否似曾相识?——LeetCode题目16:最接近的三数之和

复杂度分析

+

  • 时间复杂度:
  • 空间复杂度:

C++参考代码

+

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> res;

        if (nums.size() < 4) return res;
        
        sort(nums.begin(), nums.end());
        for (int i = 0; i < nums.size() - 3; ++i) {
            if (i > 0 && nums[i] == nums[i-1]) continue;
            for (int j = i + 1; j < nums.size() - 2; ++j) {
                if (j > i + 1 && nums[j] == nums[j-1]) continue;
                int l = j + 1, r = nums.size() - 1;
                while (l < r) {
                    int curr_sum = nums[i] + nums[j] + nums[l] + nums[r];
                    if (curr_sum == target) {
                        res.push_back({nums[i], nums[j], nums[l], nums[r]});
                        while ((l < r) && (nums[l] == nums[l+1])) ++l;
                        while ((l < r) && (nums[r] == nums[r-1])) --r;
                        ++l; --r;
                    }
                    else if (curr_sum > target) --r;
                    else ++l;
                }
            }
        }

        return res;
    }
};