力扣题目解析--四数之和

 题目

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abc 和 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

代码展示 

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        int n=nums.size();
        for(int i=0;i<n;i++){
            if(i>0&&nums[i]==nums[i-1])continue;
             for (int j = i + 1; j < n; ++j) {
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                int left = j + 1;
                int right = n - 1;
                while (left < right) {
                    long long sum = static_cast<long long>(nums[i]) + nums[j] + nums[left] + nums[right];
                    if (sum < target) {
                        ++left;
                    } else if (sum > target) {
                        --right;
                    } else {
                        result.push_back({nums[i], nums[j], nums[left], nums[right]});
                        while (left < right && nums[left] == nums[left + 1]) ++left;
                        while (left < right && nums[right] == nums[right - 1]) --right;
                        ++left;
                        --right;
                    }
                }
            }
        }
        return result;
    }
};

写者心得 

四数之和的代码和三数之和基本上就是照猫画虎,不知道的或者感兴趣的可以去看三数之和,里面详细介绍了这个双指针循环所注意用的点和它每一个步骤的作用。但是其中有几个点,是我觉得应该需要注意的。问题是在三数之和里面都没有遇到的问题。因为是四数之和嘛,所以我最初的想法是把拨出来的那个数放在 left和right之间,是这样子就造成while循环没有办法正常运行的情况。所以就把多出来的这个数放在了left之前,那就完美的解决了问题。但是后面我又遇到了,他告诉我在sum整数溢出的情况,这让我无所适从,不过后面通过查询还是解决了问题。使用这个long long可以很好的解决整数溢出的情况。接下来再遇到什么五数之和,六数之和的时候,我想所有问题就可以迎刃而解,保证双指针循环不动,在left前方加多出来的数就可以了,当然那个所加的数必须得是循环,而不能够是单独的,也就是循环的嵌套,意思是你得加一个For循环,这个多加的for循环得注意,就是你得时刻谨记你要去过滤掉那些重复的数。所以得加一个if条件。

 

代码的逐行解释 

  1. 初始化结果向量

    vector<vector<int>> result;
    • 初始化一个二维向量 result,用于存储满足条件的四元组。
  2. 排序输入向量

    sort(nums.begin(), nums.end());
    • 使用 sort 函数对输入向量 nums 进行升序排序,方便后续的双指针操作。
  3. 获取输入向量的大小

    int n = nums.size();
    • 获取 nums 的大小,存储在变量 n 中。
  4. 外层循环

    for (int i = 0; i < n; i++) {
    • 外层循环遍历 nums 的每个元素,作为第一个数。
  5. 跳过重复的元素

    if (i > 0 && nums[i] == nums[i - 1]) continue;
    • 如果当前元素 nums[i] 与前一个元素 nums[i - 1] 相同,跳过当前迭代,避免产生重复的四元组。
  6. 内层循环

    for (int j = i + 1; j < n; ++j) {
    • 内层循环遍历从 i + 1 开始的每个元素,作为第二个数。
  7. 跳过重复的元素

    if (j > i + 1 && nums[j] == nums[j - 1]) continue;
    • 如果当前元素 nums[j] 与前一个元素 nums[j - 1] 相同,跳过当前迭代,避免产生重复的四元组。
  8. 初始化双指针

    int left = j + 1;
    int right = n - 1;
    • 初始化左指针 left 和右指针 right,分别指向 j + 1 和 nums 的最后一个元素。
  9. 双指针法寻找四元组

    while (left < right) {
    • 使用双指针法,当 left 小于 right 时,继续循环。
  10. 计算当前四个数的和

    long long sum = static_cast<long long>(nums[i]) + nums[j] + nums[left] + nums[right];
    • 计算当前四个数的和 sum,使用 long long 类型防止溢出。
  11. 处理 sum 小于 target 的情况

    if (sum < target) {
        ++left;
    }
    • 如果 sum 小于 target,说明需要更大的数,移动左指针 left
  12. 处理 sum 大于 target 的情况

    else if (sum > target) {
        --right;
    }
    • 如果 sum 大于 target,说明需要更小的数,移动右指针 right
  13. 处理 sum 等于 target 的情况

    else {
        result.push_back({nums[i], nums[j], nums[left], nums[right]});
        while (left < right && nums[left] == nums[left + 1]) ++left;
        while (left < right && nums[right] == nums[right - 1]) --right;
        ++left;
        --right;
    }
    • 如果 sum 等于 target,找到一个满足条件的四元组,将其加入结果向量 result 中。
    • 跳过重复的左指针元素,避免产生重复的四元组。
    • 跳过重复的右指针元素,避免产生重复的四元组。
    • 移动左指针和右指针,继续寻找下一个可能的四元组。
  14. 返回结果

    return result;
    • 返回结果向量 result

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值