描述
输入一个递增排序的数组和一个数字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)