和为 s 的两个数字(和为 s 的连续正数序列)
题目
输入一个递增排序的数组和一个数字 s,在数组中查找两个数,得它们的和正好是 s。如果有多对数字的和等于 s,输出任意一对即可
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { if (target < nums[0]) { return {}; } vector<int> res; int i = 0, j = nums.size() - 1; while (i < j) { if (nums[i] + nums[j] == target) { res = {nums[i], nums[j]}; break; } if (nums[i] + nums[j] > target) { --j; } if (nums[i] + nums[j] < target) { ++i; } } return res; } };
题目
输入一个正数 s,打印出所有和为 s 的连续正数序列(至少两个数)
思路
考虑用两个数 small 和 big 分别表示序列的最小值和最大值。首先把 small 初始化为 1,big 初始化为 2。如果从 small 到 big 的序列的和大于 s,我们可以从序列中去掉较小的值,也就是增大 small 的值。如果从 small 到 big 的序列的和小于 s,我们可以增大 big,让这个序列包含更多的数字。因为这个序列至少要有两个数字,我们一直增加 small 到(1+s)/2 为止。
#include <iostream> #include <vector> using namespace std; class Solution { public: void find_sequence(const int &sum); }; void Solution::find_sequence(const int &sum) { if(sum<=3) return; int small=1; int big=2; int middle=(sum+1)/2; int curr_sum=small+big; while(small<middle) { if(curr_sum==sum) { for(int i=small;i<=big;++i) cout<<i<<'\t'; cout<<endl; } while(curr_sum<sum&&small<middle) { ++big; curr_sum+=big; if(curr_sum==sum) { for(int i=small;i<=big;++i) cout<<i<<'\t'; cout<<endl; break; } } curr_sum-=small; ++small; } } int main() { Solution s; s.find_sequence(15); return 0; }
code2
class Solution { public: vector<vector<int> > FindContinuousSequence(int sum) { if(sum<0) return {}; int smallNum=1,bigNum=2; vector<vector<int>> res; while(smallNum<bigNum) { int curSum=(smallNum+bigNum)*(bigNum-smallNum+1)/2; if(curSum<sum) ++bigNum; if(curSum==sum) { vector<int> tmp; for(int i=smallNum;i<=bigNum;++i) tmp.push_back(i); res.push_back(tmp); ++smallNum; } if(curSum>sum) ++smallNum; } return res; } };
拓展
通常用循环求一个连续序列的和,但每次操作后的序列和操作之前的序列比大部分都是一样的,只是增加或减少了一个数字,因此可以再之前的序列基础上求后一个序列。
浙公网安备 33010602011771号