题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
方法一:哈希法
- 求a+b=sum,如果已知a,那么b=sum-a
- 所以可以先将b添加入哈希中,然后遍历一遍数组设为a,在哈希中寻找是否存在sum-a,然后再更新乘积最小值。
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
if (array.empty()) return vector<int>();
int tmp = INT_MAX;
pair<int, int> ret;
unordered_map<int,int> mp;
for (int i=0; i<array.size(); ++i) {
mp[array[i]] = i;
}
for (int i=0; i<array.size(); ++i) {
if (mp.find(sum-array[i]) != mp.end()) {
int j = mp[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 vector<int>();
return vector<int>({array[ret.first], array[ret.second]});
}
};
方法二:双指针
- 数组有序,利用双指针,指向数组首尾,步骤如下
- 初始化:指针i指向数组首, 指针j指向数组尾部
- 如果arr[i] + arr[j] == sum , 说明是可能解
- 否则如果arr[i] + arr[j] > sum, 说明和太大,所以–j
- 否则如果arr[i] + arr[j] < sum, 说明和太小,所以++i
public ArrayList<Integer> FindNumbersWithSum(int [] array, int sum) {
List list = new ArrayList<>();
// 2+7=9; 4+5 = 9
int l = 0,r = array.length-1;
int tmp1 = 0, tmp2 = 0;
int temp = sum*sum;
while (l < r){
System.out.println(l+" "+r);
if(array[l] + array[r] < sum){
++l;
}else if (array[l] + array[r] > sum){
--r;
}else {
if (temp > array[l] * array[r]){
temp = array[l] * array[r];
tmp1 = array[l];
tmp2 = array[r];
++l;
--r;
}else {
++l;
--r;
}
}
}
if (tmp1 == 0 && tmp2 == 0) return (ArrayList<Integer>) list;
list.add(tmp1);
list.add(tmp2);
return (ArrayList<Integer>) list;
}