2023-07-15 LeetCode每日一题(四数之和)

2023-7-15每日一题

一、题目编号

18. 四数之和

二、题目链接

点击跳转到题目位置

三、题目描述

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

  • 0 <= a, b, c, d < n
  • a、b、c 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target
    你可以按 任意顺序 返回答案 。

提示:

  • 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>> res;
        int n = nums.size();
        if(n < 4){
            return res;
        }
        sort(nums.begin(), nums.end());
        for(int i = 0; i < n; ++i){
            while(i != 0 && i < n && nums[i] == nums[i-1]){
                ++i;
            }
            for(int j = i + 1; j < n; ++j){
                while(j != i + 1 && j < n && nums[j] == nums[j - 1]){
                    ++j;
                }
                int left = j + 1;
                int right = n - 1;
                while(left < right){
                    long long temp = (long long)nums[left] + nums[right] + nums[i] + nums[j];
                    if(temp < target){
                        ++left;
                    } else if(temp == target){
                        res.push_back({nums[i], nums[j], nums[left], nums[right]});
                        ++left;
                        --right;
                        while(left <= right && nums[left] == nums[left - 1]){
                            ++left;
                        }
                        while(left <= right && nums[right] == nums[right + 1]){
                            --right;
                        }
                    } else{
                        --right;
                    }
                }
            }
        }
    return res;
    }
};

五、解题思路

(1) 本道题目是三数之和的进阶版,与三数之和差别不大,如果对于三数之和还不了解的可以阅读该篇文章——2023-07-08 LeetCode每日一题(三数之和)

(2) 还是一样的思考方式,我们的题目要求的是寻找到四个数字,不重不漏的等于target。那么我们先对原始数组进行排序,这样更有利于我们进行不重不漏。

(3) 我们如果采用四层循环+哈希判断方式,时间复杂度很高,一定是无法通过题目的。所以我们要另择良木而栖。我们设置最外层循环遍历第一个数字,要使得结果中第一个数字不同,那么如果该数字与前面一个数字相同,那么该数字为该值的所有可能性都已经找出来了,没必要第一个数字还为同样的值,i++。

(4) 这个时候我们将问题转化成三数之和的问题了,只不过所要找的数字之和等于的不是target,等于的是target - nums[i]。因为在三数之和这篇文章中已经写的十分详细了,所以不多赘述。不过大致的思路与(3)中的思路相同,如何不重不漏,然后只剩下两个数字的时候通过双指针的手法减少时间复杂度即可。

你可能感兴趣的:(LeetCode每日一题,leetcode,算法,数据结构)