题目一:和为s的两个数字
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得他们的和正好是s。如果有多对这样的两个数,则输出任意一对即可。例如输入:nums = [2,7,11,15],target = 9,输出:[2,7] 或者 [7,2]。
我们看到这个题目马上就能想到的方法就是先固定一个数字,然后依次判断数组剩下的其余数字与它的和是否为s。但显然我们有更好的办法,先选择两个数字,由于数组是排好序的,如果和小于s,则考虑较小数字后面的数字。如果和大于s,则考虑较大数字前面的数字。我们定义两个指针,第一个指针指向数组的第一个数字(最小的),第二个指针指向数组的最后一个数字(最大的)。
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
int i = 0;
int j = nums.size();
while(1)
{
if(i >= j) break;
if(nums[i] + nums[j-1] == target)
{
ans.push_back(nums[i]);
ans.push_back(nums[j-1]);
break;
}
else if(nums[i] + nums[j-1] > target)
{
j--;
}
else
{
i++;
}
}
return ans;
}
题目二:和为s的连续正数序列
输入一个正数s,打印出所有和为s的连续正数序列(置少含有两个数),例如,输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以打印出3个连续序列,1 ~ 5、4 ~ 6和7 ~ 8。
有了解决前面问题的经验,我们也考虑用两个数small和big分别表示序列的最大值和最小值。small为1,big为2。如果从small到big的序列和大于s,我们可以减少small到big之间的数字数量,向后移动small。如果small到big的序列和小于s,则可以增大big,让序列包含更多的数字。由于序列里至少要包含两个数字,所以我们一直增加small直到它等于big。
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>>res;
int small = 1;
int big = 2;
while(small<big){
int ans = 0;
for(int i = small;i <= big;i++){
ans = ans+i;
}
if(ans == target){
vector<int>help;
for(int i = small;i <= big;i++){
help.push_back(i);
}
res.push_back(help);
big++;
}
else if(ans < target){
big++;
}
else{
small++;
}
}
return res;
}