面试题41:和为s的两个数字VS和为s的连续正数序列
来源:互联网 发布:spycall在淘宝怎么买 编辑:程序博客网 时间:2024/05/02 02:29
题目:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。输出描述,对应每个测试案例,输出两个数,小的先输出。
代码如下:
class Solution {public: vector<int> FindNumbersWithSum(vector<int> array,int sum) { map<int,int> map1; map<int,int> resultmap; map<int,int>::iterator iter; vector<int> vect; int i; for(i=0;i<array.size();i++) { if(map1.count(array[i])) resultmap[array[i]]=sum-array[i]; else map1[sum-array[i]]=array[i]; } int minval=INT_MAX,val,num1=0,num2=0; for(iter=resultmap.begin();iter!=resultmap.end();++iter) { val=(iter->first)*(iter->second); if(val<minval) { num1=iter->first<iter->second?iter->first:iter->second; num2=iter->first>iter->second?iter->first:iter->second; minval=val; } } if(minval!=INT_MAX) { vect.push_back(num1); vect.push_back(num2); } return vect; }};
分析一下,采用的是一个map去记录遍历过的数字,key为sum-data[i],value为该值,以便在后面出现sum-data[i],可以记录下来,这样一对就是和为sum的值对。存在resultmap中。然后寻找乘积最小的对数。时间复杂度的话我觉得是遍历O(n*lgn),count应该是lgn。
但好像并没有用到题设中的数组是排序的这一条件。于是看了书上的想法。果然精简。
class Solution {public: vector<int> FindNumbersWithSum(vector<int> array,int sum) { int i=0,j=array.size()-1; map<int,int> resultmap; map<int,int>::iterator iter; vector<int> vect; while(i<j) { if(array[i]+array[j]==sum) { resultmap[array[i]]=array[j]; i++; j--; } else if(array[i]+array[j]<sum) i++; else j--; } int minval=INT_MAX,val,num1=0,num2=0; for(iter=resultmap.begin();iter!=resultmap.end();++iter) { val=(iter->first)*(iter->second); if(val<minval) { num1=iter->first; num2=iter->second; minval=val; } } if(minval!=INT_MAX) { vect.push_back(num1); vect.push_back(num2); } return vect; }};思路也很清楚,因为是排序数组,如果array[i]+array[j]>sum;说明大了,j减一个,如果小了,i加一个。
该题还有一种扩展:
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序。
同时考虑small和big分别为最小,最大值。如果从small到big的最大值小于sum,则增加big,否则增加small(相当于丢弃原来的small,值减小),代码如下:
class Solution {public: vector<vector<int> > FindContinuousSequence(int sum) { vector<vector<int> > result; int small=1; int big=2; int j; int middle=(1+sum)/2; int cursum=small+big; while(small<middle) { if(cursum==sum) { InsertToVect(result,small,big); cursum-=small; small++; } else if(cursum<sum) { big++; cursum+=big; } else { cursum-=small; small++; } } return result; } void InsertToVect(vector<vector<int> > & v,int small,int big) { vector<int> vect; int i; for(i=small;i<=big;i++) vect.push_back(i); v.push_back(vect); }};
0 0
- 剑指offer面试题41和为s的两个数字VS和为s的连续正数序列
- [剑指offer][面试题41]和为s的两个数字 VS 和为s的连续正数序列
- 面试题41:和为s的两个数字VS和为s的连续正数序列
- 面试题41:和为s的两个数字VS和为s的连续正数序列
- 剑指offer 面试题41—和为s的两个数字VS和为s的连续正数序列
- 【剑指Offer学习】【面试题41:和为s 的两个数字vs 和为s 的连续正数序列】
- 面试题41和为S的两个数字VS和为s的连续正数序列
- 剑指offer-面试题41:和为s的两个数字VS和为s的连续正数序列
- 剑指offer之面试题41和为s的两个数字VS和为s的连续正数序列
- 面试题41:和为s的两个数字 VS 和为s的连续正数序列
- 面试题41:和为s的两个数字VS和为s的连续正数序列
- 剑指offer--面试题41:和为S的两个数字 vs 和为S的连续正数序列
- 剑指Offer-面试题41-和为s 的两个数字vs 和为s 的连续正数序列
- 剑指offer-面试题41-和为s的两个数字VS和为s的连续正数序列
- 剑指offer 面试题41 和为 s 的两个数字 VS 和为 s 的连续正数序列
- 面试题41:和为s的两个数字VS和为s的连续正数序列
- 剑指Offer_面试题41_和为s的两个数字 VS 和为s的连续正数序列
- 面试题41:和为s的两个数字,和为s的连续正数序列
- java基础总结_03
- cesiumjs开发实践 (一)
- 搭建Dubbo+Zookeeper
- drawable文件夹详解
- poj 1693 模拟
- 面试题41:和为s的两个数字VS和为s的连续正数序列
- JSON
- 【杭电-oj】-1002-A + B Problem II(大数相加)
- 本地通知 UILocalNotification
- 移植apache-1.3.39到arm平台
- git不区分大小写
- 二维码的生成 lizbqrencode遇到的问题
- 【链表】C++链表反转、链表逆序打印
- xmpp配置服务器