题目:
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
要点:
1、递增排序
2、和为S
3、乘积最小,a*b=S,要使乘积最小,也就是|a-b|最大;乘积最大,也就|a-b|最小
乘积最小
方法及思路:
1、双指针min 和max:
a[min]+a[max]等于sum,则找到;
如果和小于sum,则将min++;
如果和大于sum,则将max–。
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum)
{
vector<int> ret;
if(array.size() < 2) return ret;
int min = 0, max = array.size() - 1;
while(min < max)
{
if(array[min] + array[max] == sum)
return {array[min] , array[max]};
else if(array[min] + array[max] > sum)
max--;
else
min++;
}
return ret;
}
};
2、哈希表unordered_map<int, int> res;
(https://www.cnblogs.com/wzw0625/p/12550425.html)
初始化map;
遍历a,查找res[target - nums[i]]的存在即可
lass Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> res;
vector<int> arr;
if(nums.size() < 2) return nums;
for(int i = 0; i < nums.size(); i++)
{
res[nums[i]] = 1; //初始化
}
for(int i = 0; i < res.size(); i++)
{
if(res[target - nums[i]] != 0)
{
arr.push_back(nums[i]);
arr.push_back(target - nums[i]);
break;
}
}
return arr;
}
};
3、暴力
for(int i = 0; i < a.size() - 1; i++)
for(int j = i + 1; j < a.size(); j++){}
乘积最大
1、双指针
(S/2)*(S/2)是乘积最大的两个数字
所以查找S/2的位置,然后使用双指针,再次查找:
1、二分查找,找到| a[start] - S/2|最小的值位置start
2、left=start,right = start+1:
如果和等于S,输出
如果和大于S,left–;
如果和小于S,right++;
2、哈希表
```cpp
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum)
{
vector<int> ret;
if(array.size() < 2) return ret;
unordered_map<int, int> res;
for(int i = 0; i < res.size(); i++)
{
if(res[target - nums[i]] != 0)
return {nums[i], target - nums[i]};
res[nums[i]] = i;
}
return arr;
}
};
和为S的连续子序列
参考:https://blog.csdn.net/zhenaoxi1077/article/details/81013205
待验证