和为 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;
    }
};

拓展

  通常用循环求一个连续序列的和,但每次操作后的序列和操作之前的序列比大部分都是一样的,只是增加或减少了一个数字,因此可以再之前的序列基础上求后一个序列。

posted on 2019-01-21 16:42  tianzeng  阅读(197)  评论(0)    收藏  举报

导航