两数之和,本题是2022年1月22日举办的第13届蓝桥杯青少组Python编程选拔赛真题编程部分第4题。题目要求对于给定的一组正整数和目标值,编程找出两个正整数,要求其和离目标值最接近。
先来看看题目的要求吧。
编程实现:
给出一组正整数数据和一个正整数(目标值),从这组正整数中找出两个数,使这两个数相加后的和,小于等于目标值并且离目标值最接近,然后将两个数的和输出。
如:正整数数据为[9, 4, 3, 5],目标值为10,其中正整数数据中4和3、4和5、3和5 的和都小于目标值10,但离目标值最接近的两个数是4和 5,其和为9。
输入描述:
第一行输入一组长度大于 3 个正整数的数据(正整数 < 10000),正整数之间以一个英文逗号隔开
第二行输入一个正整数 n(1 < n < 19997),表示目标值
输出描述:
输出一个整数。
如果正整数数据中存在小于等于目标值并且离目标值最接近的两个数,则输出这两个数的和;
如果正整数数据中不存在这样的两个数,即正整数数据中任意两个数的和都超过了目标值,则输出-1
样例输入:
9,4,3,5
10
样例输出:
这是一道简单的算法题,涉及的知识点包括循环、条件语句和列表等。
嵌套循环 使用combinations()函数
所谓双指针是指在遍历列表的过程中,不是使用单个指针进行访问,而是使用两个指针进行访问,从而达到相应的目的。
最简单的双指针是对撞指针,它指的是使用两个指针left、right分别指向列表第一个元素和最后一个元素,然后left指针不断递增,right不断递减,直到两个指针的值相撞(即 left== right),或者满足其他要求的特殊条件为止。
双指针利用了区间单调性的性质,可以将时间复杂度降到 O(n)。
思路有了,接下来,我们就进入具体的编程实现环节。
枚举算法
使用combinations()函数
双指针算法
1. 枚举算法
根据前面的思路分析,我们使用嵌套循环编写代码如下:
代码不多,说明两点:
1). res表示最终的结果,初始值为-1,如果不存在小于target的情况,就直接输出-1;
2). 注意i和j的范围,前者从0开始到len(nums) - 1,后者从i+1开始,一直到最后一个列表项。
2. 使用combinations()函数
combinations()函数可以帮我们生成所有可能的两个数的组合,原来的两层循环可以简化为一层,对应的代码如下:
要使用combinations()函数,必须先导入。
3. 双指针算法
根据前面的思路分析,编写代码如下:
代码稍微要复杂一点,简单说明两点:
1). 使用双指针算法,要确保nums列表是有序的;
2). 当left < right,计算两数之和,并不断调整left和right指针,当两个指针撞到一起了,循环结束。
至此,整个程序就全部完成了,你可以输入不同的数字来测试效果啦。
循环语句;
列表操作;
输入输出处理;
组合函数;
本题代码不多,难度中等,关键点是要理解题目的意思,这里要寻找小于等于target的两数和,并且是最接近target的。小于等于target的两数和可能有很多个,所谓最接近target,就是在满足条件的两数和中找最大的。
在计算机编程中,最常用的算法就是暴力枚举,这也是计算机最擅长的事情。
但是,暴力枚举要将所有的情况都列举出来,随着数据规模的增加,时间复杂度会急剧增加。因此,我们需要寻找更聪明的枚举方法,根据不同的问题和场景,可以采取不同的优化策略,也就产生了各种不同的算法。
本题中的双指针算法就是一个非常好的优化技巧,在编程中会经常用到,比如字符串反转、判断回文数和快速排序等。
你还有什么好的想法和创意吗,也非常欢迎和超平老师分享探讨。
需要源码的,可以添加本人微信。
另外,超平老师创建了一个蓝桥杯备考交流群,这是专门为老师和家长打造的免费社群,您可以与来自全国各地的老师、家长共同交流经验,分享学习心得。
超平老师也会给大家带来及时的赛事动态,备考攻略,真题资源分享,帮助各位更好地备考第15届蓝桥杯赛事,力争取得优异的成绩。
扫码或长按加入微信群