我是靠谱客的博主 和谐大叔,最近开发中收集的这篇文章主要介绍74、【数组】leetcode——18. 四数之和(C++版本)题目描述解题思路,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目描述

在这里插入图片描述
在这里插入图片描述
原题链接:18. 四数之和

解题思路

思路与三数之和:15. 三数之和,区别之处在于:

1、多一层for循环,用于多加一个数。

四数之和就是在三数之和多加一个数,用前两个数相加,后面两个数继续作为双指针移动判定。

2、剪枝判定条件。

(1)第一层的i,在三数之和中的条件为nums[i] > 0,此时为target,但不能直接用nums[i] > target,因为可能会出现target为和nums[i]都为负数时,尽管nums[i]大于target,但可能nums[i]后续还有负数,相加后就有可能等于target,例如:[-2,-1,0,0]target=-3,当nums[i]=-2时,nums[i]>target,但后续还有一个-1,可让相加后为-3。
因此,判定条件应为nums[i] > target && (target >= 0 || nums[i] >= 0),此时后续一定无满足相加后等于target的条件。

(2)第二层的j,思路同上,判定条件为nums[j] + nums[i] > target && (target >= 0 || nums[j] >= 0)。本应为nums[i] + nums[j]>=0,但若想让该数大于等于0,那么只可能是如下两种情况:nums[i]>=0nums[i]<0。可知上述三种情况下,一定都会是nums[j]>=0时,才有nums[i] + nums[j]>=0,故另一个判定条件为nums[j]>=0即可。

3、去重判定条件。

(1)第一层的i,与三数之和相同,判定条件为i > 0 && nums[i] == nums[i - 1]
(2)第二层的j,要确保第一次j=i+1时,没有未被记录元素被去掉,因此判定条件为j > i + 1 && nums[j] == nums[j - 1]

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        for(int i = 0; i < n - 3; i++) {
            // 剪枝,避免target为负数被剪枝的情况
            if(nums[i] > target && (target >= 0 || nums[i] >= 0))       break;
            // 去重
            if(i > 0 && nums[i] == nums[i - 1])      continue;
            for(int j = i + 1; j < n - 2; j++) {
                // 剪枝
                if(nums[j] + nums[i] > target && (target >= 0 || nums[j] >= 0))     break;
                // 去重,此时要保证j > i + 1,避免j = i + 1时,有未记录元素被去掉
                if(j > i + 1 && nums[j] == nums[j - 1])     continue;
                int l = j + 1, r = n - 1;
                while(l < r) {
                    while(l < r && (long)nums[i] + nums[j] + nums[l] + nums[r] < target)      l++;
                    while(l < r && (long)nums[i] + nums[j] + nums[l] + nums[r] > target)      r--;
                    if(l < r && (long)nums[i] + nums[j] + nums[l] + nums[r] == 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--;
                    }
                }
            }
        }
        return res;
    }
};

时间复杂度 O ( n 3 ) O(n^3) O(n3)
空间复杂度 O ( l o g n ) O(log n) O(logn) (忽略存储答案的空间,额外的排序的空间复杂度为 O ( l o g n ) O(log n) O(logn)

参考文章:第18题. 四数之和、15. 三数之和

最后

以上就是和谐大叔为你收集整理的74、【数组】leetcode——18. 四数之和(C++版本)题目描述解题思路的全部内容,希望文章能够帮你解决74、【数组】leetcode——18. 四数之和(C++版本)题目描述解题思路所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部