双指针问题
和为S的两个数字
题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
思路
数组是递增排序的,双指针从头尾向中间移动
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
// 双指针问题
// 重点:升序排列 + 两个数乘积最小 ===> 从两边向中间移动双指针
// 是否需要比较乘积大小?
int l = 0;
int r = array.size()-1;
vector<int>res;
while(l<r){
if(array[l]+array[r]>sum){
r--;
}else if(array[l]+array[r]<sum){
l++;
}else{
res.push_back(array[l]);
res.push_back(array[r]);
return res;
}
}
// 这里需要加一个return res; 否则报错 段错误
// 不存在满足 和为sum的情况时 返回空res
return res;
}
};
和为S的连续正数序列
题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
思路
连续正数序列,数组是递增排序的,需要计算前缀和,双指针从头一起向后移动。
class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int> >res;
int l = 1;
int r = 2;
if(l+r>sum)return res;
vector<int>preSum(1,0);
for(int i=1;i<=sum;i++){
preSum.push_back(preSum[i-1]+i-1);
}
while(l<=r-1&&r<=sum){
if(preSum[r] + r - preSum[l]>sum){
l++;
}else if(preSum[r] + r - preSum[l]<sum){
r++;
}else{
vector<int> restemp;
for(int k=l;k<=r;k++)
restemp.push_back(k);
res.push_back(restemp);
l++;
r++;
}
}
return res;
}
};