• 27 和为S的两个数字


    0 引言

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

    1 抽象问题具体化

    举例: 序列为{1,2,3,4,5,6,7,8,9}, 和为10

    解答:如下图所示,一头一尾两个指针分别运动,找到和为10的两个数,并比较其乘积,得到乘积最小的两个数作为结果输出。

      1*9 = 9;

      2*8 = 16;

      3*7 = 21;

      4*6 = 24;

      

    2 具体问题抽象分析

    算法描述:设序列为array,和为sum

    (1)将两个指针初始化为序列头(p)尾(q)两项;

    (2)如果两个数的和小于sum(array[p] + array[q] < sum),则考虑增大p,使得和值增大;

    (3)如果两个数的和大于sum(array[p] + array[q] > sum),则考虑减小q,使得和值减小;

    (4)如果两个数的和等于sum(array[p] + array[q] == sum),则考虑增大p或者减小q,使得遍历继续,同时根据两数的乘积更新最小乘积以及输出值;

    (5)返回结果

    3 demo

    /* 寻找递增序列中和为sum的两个数
    * 输入1: vector<int> array,递增序列
    * 输入2: int sum, 和
    * 输出:  vector<int>格式,两个数,其和等于sum,乘积最小
    * 算法思路描述:一头一尾两个指针分别运动,记录其和值中乘积最小的一个
    */
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        vector<int> twoNums{0,0};
        if(array.size() < 2){
            twoNums.clear();
            return twoNums;
        }
        int minMultiplication = pow(array[array.size()-1],2);
        for(int p=0, q=(int)array.size()-1; p != q;){
            if(array[p] + array[q] < sum)
                ++ p;
            else if(array[p] + array[q] > sum)
                -- q;
            else{
                if(array[p] * array[q] <= minMultiplication){
                    minMultiplication = array[p] * array[q];
                    twoNums[0] = array[p];
                    twoNums[1] = array[q];                   
                }                
                -- q; // 或者++ p;
            }          
        }
        if(twoNums[0] == 0 && twoNums[1] == 0)
            twoNums.clear();        
        return twoNums;        
    }

    4 代码优化

  • 相关阅读:
    HDU
    HDU
    HDU
    HDU
    西电网络赛
    西电网络赛
    西电网络赛
    西电网络赛
    西电网络赛
    西电网络赛
  • 原文地址:https://www.cnblogs.com/ghjnwk/p/10162511.html
Copyright © 2020-2023  润新知