leetcode:四数之和(详解)

news/2024/11/8 0:33:19/

内容:题目,代码实现及注解,思路详解

题目:

给你一个由 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 = [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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/4sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

代码实现:

int cmp(const void*e1,const void*e2){return *(int*)e1 - *(int*)e2;}int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes)
{*returnSize = 0;if(nums==NULL || numsSize<4){return NULL;}qsort(nums,numsSize,sizeof(int),cmp);//排序int**ret = (int**)malloc(sizeof(int*)*numsSize*numsSize);* returnColumnSizes = (int*)malloc(sizeof(int)*numsSize*numsSize);int i = 0;for(i=0;i<numsSize-3;i++)//枚举确定第一个数{if(i>0 && nums[i]==nums[i-1])//排除第一个数的重复项{continue;}if((long)nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target)//剪枝1:第一个数+最小的三数组合>target,则它及其之后所有枚举的第一个数都不符合要求,直接break,退出枚举循环{break;}if((long)nums[i]+nums[numsSize-1]+nums[numsSize-2]+nums[numsSize-3]<target)剪枝2:第一个数+最大的三数组合<target,则当前枚举的第一个数无论怎样与后面的三个数组合都不可能=target,跳过当前枚举的第一个数{continue;}int j = 0;for(j=i+1;j<numsSize-2;j++)//枚举确定第二个数{if(j>i+1 &&nums[j]==nums[j-1])//排除第二个数的重复项{continue;}if((long)nums[i]+nums[j]+nums[j+1]+nums[j+2]>target)//剪枝1:第一个数固定后,当前枚举的第二个数,再挑选最小的两数组合,四数之和若>target,则当前枚举的第二个数及其后面所有的枚举都不符合要求,直接break{break;}if((long)nums[i]+nums[j]+nums[numsSize-1]+nums[numsSize-2]<target)//剪枝2:第一个数固定后,当前枚举的第二个数,再挑选最大的两数组合,四数之和若<target,则当前枚举的第二个数,无论再怎么与后面的两数组合,四数之和都<target,则跳过当前枚举的第二个数{continue;}//以下是在固定住前面两数之和,使用双指针法组合后面的两数之和,使得四数之和==targetint left = j+1;int right = numsSize-1;while(left<right){long sum =(long) nums[i]+nums[j]+nums[left]+nums[right];if(sum==target){ret[*returnSize] = (int*)malloc(sizeof(int)*4);ret[*returnSize][0] = nums[i];ret[*returnSize][1] = nums[j];ret[*returnSize][2] = nums[left];ret[*returnSize][3] = nums[right];(* returnColumnSizes)[*returnSize] = 4;(*returnSize)++;
//排除与确定组合重复的所有项:while(left<right && nums[left]==nums[++left]);while(left<right && nums[right]==nums[--right]);}else if(sum<target){while(left<right && nums[left]==nums[++left]);//排除不符合要求的重复项}else if(sum>target){while(left<right && nums[right]==nums[--right]);//排除不符合要求的重复项}}}}return ret;
}

思路详解:

方法:双重循环枚举前两数的组合+双指针法寻求后两数之和

首先对数组进行升序排序

1 双重循环:

第一重循环枚举确定第一个数:

a 排除枚举第一个数出现的重复项,continue的作用是跳过本轮循环,进入下一轮循环

b 剪枝1:第一个数确定后,与最小的三数组合相加,结果>target,说明当前枚举的第一个数及其后面所有枚举的第一个数都不能用,因为是升序,那就break,退出第一个数的枚举循环

   剪枝2:第一个数确定后,与最大的三数组合相加,结果<target,说明当前枚举的第一个数无论怎样与后面任意挑选的三个数组合,结果都不可能=target,又由于是升序,当前枚举的第一个数不行,那就换下一个枚举的第一个数,跳过本轮循环,进入下一轮循环,后面枚举的第一个数中可能存在符合要求的

第二重循环枚举确定第二个数:

a 排除枚举第二个数出现的重复项,continue的作用是跳过本轮循环,进入下一轮循环

b 剪枝1:第一个数固定后,当前枚举的第二个数,再与挑选的最小的两数相加,四数之和若>target,则说明当前枚举的第二个数与后面所有枚举的第二个数都不可用,直接break退出第二个数的枚举循环

 剪枝2:第一个数固定后,当前枚举的第二个数,再与挑选的最大的两数相加,四数之和若<target

 则说明当前的第一个数字与第二个数字无论怎样与后面的两数组合,都不可能满足要求,又由于是升序,则跳过本轮枚举的第二个数,进入下一轮枚举的第二个数 ,后面枚举的第二个数中可能存在符合要求的

2 双指针组合两数之和:

需要注意的是四数之和可能超过整型范围,所有需要对其中的任意一个数进行long类型的强制转换,这样就不会出现整型溢出的现象了

两数之和的详解我已经写过,不再赘述:http://t.csdn.cn/JNfQ7


http://www.ppmy.cn/news/911159.html

相关文章

CAN转ETHERCAT网关can协议和canfd协议

大家好&#xff0c;今天要跟大家分享一款自主研发的通讯网关&#xff0c;YC-ECT-CAN。这款产品能够将各种CAN总线和ETHERCAT网络连接起来&#xff0c;实现高效的数据传输和通信。那么&#xff0c;这款通讯网关具体有哪些功能和特点呢&#xff1f;接下来&#xff0c;我们就一起来…

刷脸支付帮助店铺构建细致准确的用户画像

蜻蜓是支付宝在2018年年底推出的一款“刷脸”支付产品&#xff0c;摆放在收银台上&#xff0c;顾客在付款时先输入手机号码&#xff0c;然后面对摄像头进行人脸识别&#xff0c;几秒钟便可成功支付。作为目前人脸识别技术最广泛的一种应用方式&#xff0c;“刷脸”支付逐渐在全…

商业银行纷纷发力聚合支付:进行费率补贴 即时生成收款码

候维科技随着移动支付的普及发展&#xff0c;商家的“收银台”也在发生变革。近日&#xff0c;津云记者发现&#xff0c;不少商家的“收银台”开始变得清爽起来&#xff0c;从原来架着多个收款二维码变成了单个银行的“聚合支付”收款码。津云记者了解到&#xff0c;从2018年开…

中信银行上线票付通产品 为电商打造专属电票服务

中新网1月30日电 日前&#xff0c;随着银耐联平台817万元耐火材料订单的线上票据支付成功&#xff0c;中信银行“票付通”产品实现上线投产。作为上海票据交易所第一批试点金融机构&#xff0c;中信银行首发推出业内全新的电票支付产品&#xff0c;开启了电商电票支付新历程。 …

3.2 金融服务

自有人类社会以来&#xff0c;金融交易就是必不可少的经济活动&#xff0c;涉及货币、证券、保险、抵押、捐赠等诸多行业。交易角色和交易功能的不同&#xff0c;反映出不同的生产关系。通过金融交易&#xff0c;可以优化社会运转效率&#xff0c;实现资源价值的最大化。可以说…

理解LLM中的ReAct

large language models (LLMs)大语言模型在语义理解和交互式决策方面有着不错的表现。ReAct在一次交互中循环使用推理和行动两个操作解决复杂问题&#xff0c;推理即利用模型自身语义理解能力&#xff0c;行动则利用模型以外的能力&#xff08;如计算、搜索最新消息&#xff0c…

数字人民币与智能合约

7月16日&#xff0c;中国人民银行在官网发布了《中国数字人民币的研发进展白皮书》&#xff08;以下简称“白皮书”&#xff09;&#xff0c;以阐明人民银行在数字人民币研发上的基本立场&#xff0c;阐释数字人民币体系的研发背景、目标愿景、设计框架及相关政策考虑。 “白皮…

[渝粤教育] 中央财经大学 审计学 参考 资料

教育 -审计学-章节资料考试资料-中央财经大学【】 随堂测试题1.1 1、【单选题】注册会计师审计产生的直接原因是( )。 A、所有权和经营权的分离 B、合伙企业制度的产生 C、股份制企业制度的形成 D、资本市场的发展 参考资料【 】 随堂测试1.2 1、【多选题】甲、乙、丙三人成立一…