剑指Offer-57:和为s的数字

题目一:和为s的两个数字

输入一个递增排序的数组和一个数字,在数组中查找两个数,使得他们的和正好是s,如果有多对数字的和等于s,则输出任意一对即可。

链接:

剑指Offer(第2版):P280

思路标签:

  • 算法:双指针

解答:

  • 需要注意题目中给出的条件:递增排序数组。要利用数组排序的性质;
  • 使用两个指针,一个指针指向数组的第一个元素,一个数组指向最后一个元素;
  • 如果二者的和小于目标和,小指针向前移动;如果二者的和大于目标和,则大指针向后移动。
  • 算法是基于递增的性质,如果不是递增则使用hash表来解决。
class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        vector<int> result;
        int length = array.size();
        if(length <= 0)
            return result;

        int start = 0;
        int end = length - 1;
        while(start < end){
            int curSum = array[start] + array[end];
            if(curSum == sum){
                result.push_back(array[start]);
                result.push_back(array[end]);
                break;
            }
            else if(curSum > sum)
                end--;
            else
                start++;
        }
        return result;
    }
};

题目二:和为s的连续正数序列

输入一个正数s,输出所有和为s的连续正数序列(至少含有两个数)。

例子:

输入15,由于1+2+3+4+5=4+5+6=4+5+6=7+8=15,所以打印出3个连续序列1~5、4~6和7~8.

链接:

剑指Offer(第2版):P282

思路标签:

  • 算法:双指针

解答:

  • 还是以上面类似的思路,使用双指针来解决;
  • 小指针初始为1,大指针初始为2;
  • 如果从小到大的数字的和大于目标和,则抛弃小指针当前值,也就是小指针加1;如果从小到大数字的和小于目标和,则增加大指针;
  • 注意循环的边界条件:samll
class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int> > ret;
        if(sum < 3)
            return ret;

        int small = 1;
        int big = 2;
        int middle = (1+sum)/2;
        int curSum = small + big;
        while(small < middle && big < sum){
            while(curSum > sum){
                curSum -= small;
                small++;
            }
            if(curSum == sum)
                InsertRet(small, big, ret);

            big++;
            curSum += big;
        }
        return ret;
    }

    void InsertRet(int small, int big, vector<vector<int> > &ret){
        vector<int> temp;
        for(int i=small; i<=big; ++i)
            temp.push_back(i);

        ret.push_back(temp);
        return;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值