力扣18 四数之和(C++)

题目


知识点

剪枝处理

负数处理

举例说明

假设:数组中有负数,比如 -5, -4, -2, 1, 3,target = -10

当前 numsk = -5,情况分析:-5 > -10 成立(因为 -5 确实大于 -10),

但如果没有 numsk >= 0 的限制,我们会直接 break,跳过了后续可能的解

实际上,-5 可以和 -4、-2、1 组合成 -10(-5 + -4 + -2 + 1 = -10)!

为什么需要 >= 0?

负数相加会变得更小:当数组中有负数时,即使当前数已经大于 target,加上后面的负数后,总和可能会变小,仍然可能等于 target。

非负数才具有单调性:只有当数组元素都大于等于 0 时,随着索引增加,和才会单调递增。这样一旦当前数大于 target,后面更大的数相加只会更大,肯定无法等于 target。

去重


思路

15 三数之和 都是一样的思路,利用排序+双指针 ,但是要再多加一层for循环


题解

cpp 复制代码
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> result;
        for(int k=0;k<nums.size();k++){
            //一级剪枝处理
            if(nums[k]>=0 && nums[k]>target){
                break;
            }

            //一级去重
            if(k>0 && nums[k]==nums[k-1]){
                continue;
            }

            for(int i=k+1;i<nums.size();i++){
                //二级剪枝处理
                if(nums[k]+nums[i]>=0 && nums[k]+nums[i]>target){
                    break;
                }

                //二级去重
                if(i>k+1 && nums[i]==nums[i-1]){
                    continue;
                }

                int left=i+1;
                int right=nums.size()-1;
                while(left < right){
                    if((long)nums[k]+nums[i]+nums[left]+nums[right]>target) right--;
                    else if((long)nums[k]+nums[i]+nums[left]+nums[right]<target) left++;
                    else{
                        result.push_back(vector<int>{nums[k],nums[i],nums[left],nums[right]});
                        while(left<right&&nums[left]==nums[left+1]) left++;
                        while(left<right&&nums[right]==nums[right-1]) right--;
                        left++;
                        right--;
                    }
                }
            }//for i
        }//for k
        return result;
    }
};
相关推荐
伊玛目的门徒6 小时前
试用leetcode之典中典 二数之和问题
java·算法·leetcode
Jerry7 小时前
LeetCode 226. 翻转二叉树
算法
想做小南娘,发现自己是女生喵8 小时前
【无标题】
数据结构·算法
Kx_Triumphs10 小时前
HDU4348 To the moon(主席树区间修改模板)
算法·题解
旖-旎10 小时前
《LeetCode647 回文子串 || LeetCode 5 最长回文子串》
c++·算法·leetcode·动态规划·哈希算法
轻颂呀11 小时前
约瑟夫环问题
算法
凤凰院凶涛QAQ12 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
科技大视界13 小时前
投资AI项目,传统尽调不够用了——李章虎律师拆解算法、数据、算力三大雷区
人工智能·算法·数据挖掘
郝学胜-神的一滴13 小时前
算法实战:最小k个数——大顶堆的优雅解法
开发语言·数据结构·c++·python·程序人生·算法·排序算法