第42题 和为S的两个数字
题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
if(array.empty()) return {};
pair<int,int> ret;
int i = 0,j= array.size()-1;
int tmp = INT_MAX;
while(i<j){
if((array[i]+array[j])==sum){
if(tmp>(array[i]*array[j])){
tmp = array[i]*array[j];
ret = {i,j};
}
++i, --j;
}else if((array[i]+array[j])>sum){
--j;
}else{
++i;
}
}
if(ret.first == ret.second) return {};
return vector<int>({array[ret.first],array[ret.second]});
}
};
思路:
由于是递增数组,所以可以使用一头一尾双指针。如果当前这对值大于要求的和,则递减右指针,如果小于要求的和,则递增左指针,如果恰好等于,则判断是否更新,然后同时递增左指针,递减右指针。最后返回结果。
哈希版本
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
if(array.empty()) return {};
unordered_map<int,int> m;
pair<int,int> ret;
int tmp = INT_MAX;
for(int i = 0;i<array.size();++i){
m.insert(make_pair(array[i],i));
}
for(int i = 0;i<array.size();++i){
if(m.find(sum-array[i])!=m.end()){
int j = m[sum-array[i]];
if(j>i && array[i]*array[j]<tmp){
tmp = array[i]*array[j];
ret = {i,j};
}
}
}
if(ret.first == ret.second) return {};
return vector<int>({array[ret.first],array[ret.second]});
}
};