【LeetCode & 剑指offer刷题】数组题2:57 有序数组中和为s的两个数(167 Two Sum II - Input array is sorted)

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

57 有序数组中和为s的两个数

题目描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S输出两个数的乘积最小的

输出描述:

对应每个测试案例,输出两个数,小的先输出。
 
#include <climits>
class Solution
{
public:
    vector<int> FindNumbersWithSum(vector<int> a,int sum)
    {
        if(a.size()<2) return vector<int>();
       
        int min_product = INT_MAX;
        int left = 0, right = a.size()-1;
        int a1,a2;
        bool find_flag = false;
        while(left < right) //从两边开始往中间扫描
        {
            int cursum = a[left] + a[right];
            if(cursum > sum) right--;
            else if(cursum < sum) left++;
            else
            {
                //因为对于递增序列,一定有x*y < (x+a)*(y-a),故这里其实可以不用判断
                //从两边开始往中间扫描时,找到的第一个即为乘机最小的一对数
                if(a[left]*a[right] < min_product)
                {
                    find_flag = true;
                    min_product = a[left]*a[right];
                    a1 = a[left];
                    a2 = a[right];
                }
                left++; //继续扫描
            }
        }
        if(find_flag) return vector<int>{a1,a2};
        else return vector<int>();
       
    }
};
 
拓展:和为S的连续正数序列

题目描述

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

输出描述:

输出所有和为S的连续正数序列(指1、2、3、4等)。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
class Solution
{
public:
    vector<vector<int> > FindContinuousSequence(int sum)
    {
        vector<vector<int>> result;
        if(sum < 3) return result; //至少需包含两个数 
       
        int left = 1, right = 2//序列从1开始
        while(left < right//注意从开头开始扫描,直到left与right相遇
        {
            int cursum = (left+right)*(right - left + 1)/2; //用等差数列的求和公式
            if(cursum < sum) right++;
            else if(cursum > sum) left++;
            else
            {
                vector<int> temp;
                for(int i = left; i <= right; i++)
                    temp.push_back(i);
                result.push_back(temp); //push符合要求的连续正数序列
                left++; //继续下个序列的寻找
            }
        }//最后退出循环时,left = right = sum/2+1的位置,比如找10,最后指向 5、6,再均指向6,退出循环
        return result;
    }
};
 
 

 

posted @ 2019-01-05 13:38  wikiwen  阅读(256)  评论(0编辑  收藏  举报