描述
        输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回两个数的乘积最小的,如果无法找出这样的数字,返回一个空数组即可。
返回值描述
对应每个测试案例,输出两个数,小的先输出。
示例1
输入:
[1,2,4,7,11,15],15
返回值:
[4,11]

方法一:双指针法
核心思想:
        由题意可知,给出的数组为一个递增有序的数组。同时需要在数组中寻找两个数的和等于给定的数字S,在多组结果的时候返回乘积最小的结果。采用左右指针遍历数组数据,初始时,左指针指向p1第一个元素,右指针pn指向最后一个元素。每次统计左右指针指向的元素和,当元素和等于S的时候记录这两个数,同时记录这两个数的乘积product,每次遇到两数和为S的时候,都需要比较最新的两数乘积与之前记录的product的大小,如果当前两数乘积更小,则更新数组和两数乘积product

存在三种情况如下:
1)左右指针所指元素和等于S
        ① 两数的乘积 < product; 更新数组,同时更新两数乘积product
        ② 两数的乘积 >= product; 逃过此次更新操作
        ③ 左指针向右移动,右指针右左移动
2)左右指针所指元素的和大于S
        右指针向左移动
3)左右指针所指元素的和小于S
        左指针向右移动

结束条件:当指针p1和指针pn重合的时候即跳出循环
边界条件:当数组元素小于2或者不存在这样的数据对时,结果直接返回空数组


图解:
图片说明

核心代码:

vector<int> FindNumbersWithSum(vector<int> array,int sum) {
    if(array.size()<2)
        return {};
    vector<int> result(2); 
    int len = array.size(),p1,pn,product = INT_MAX;
    p1 = 0,pn = len-1;   //左右指针
    bool existPair = false;     //标志是否存在这样的数组对
    while(p1<pn){
        if((array[p1]+array[pn]) == sum){     //两数和等于sum
            existPair = true;
            if(array[p1]*array[pn] < product){
                result[0] = array[p1];
                result[1] = array[pn];
                product = array[p1]*array[pn];   //更新最新的两数乘积
            }
            p1++;
            pn--;
        }else if((array[p1]+array[pn]) > sum){   //两数和大于sum
            pn--;
        }else{             //两数和小于sum
            p1++;
        }
    }
    if(!existPair)     //不存在这样的数据对
        return {};
    return result;
}

时间复杂度O(n)
空间复杂度O(1)


方法二:哈希集合
核心思想:
        用哈希集合记录不重复的数组元素,每次迭代数组元素的时候,需要判断sum与当前元素的差值是否在哈希集合中,存在则比较两数乘积与product(记符合条件的两数乘积),否则不做处理。每次遍历都需要将当前元素插入到集合中。判断sum与当前元素的差值存在哈希集合中时,有如下几种情况:
1)当前元素和sum与当前元素的差值的乘积 < product; 更新结果数组,同时更新product
2)当前元素和sum与当前元素的差值的乘积 >= product;不做任何处理

边界条件:当这样的数据对不存在的时候则返回空数组(用一个标志位记录即可)
注意事项:存在这样的数据对时,则需要将当前元素存放在数据对中的第二个元素的位置,而sum和当前元素的差值存放在数据对中的第一个元素的位置。这是因为越往后遍历,数据值越大。

图解:
图片说明

核心代码:

vector<int> FindNumbersWithSum(vector<int> array,int sum) {
    unordered_set<int> search;
    int product = INT_MAX;
    vector<int> result(2);
    bool existPair = false;     //标志是否存在这样的数组对
    for(auto item:array){
        if(search.count(sum-item)){    //存在这样的结果数组
            existPair = true;
            if(item * (sum-item) < product){     //这里面需要将第一个和第二个元素反过来,因为遍历约到后面的时候数据越大,而差值这越小
                result[0] = sum-item;
                result[1] = item;
                product = item * (sum-item);   //更新最新的两数乘积
            }
        }
        search.insert(item);
    }
    if(!existPair)
        return {};
    return result;
}

时间复杂度O(n)
空间复杂度O(n)