剑指offer——和为S的数字*

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

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

输出描述:

对应每个测试案例,输出两个数,小的先输出。

 

解题思路:

设置两个指针分别指向数组的首位和末位,如果两个指针指向的数字和大于sum尾指针向前移动一位,若小于sum首指针向后移动一位,若与sum相等表示找到了,保存退出循环。

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        vector<int> res;
        if(array.size()==0) return res;
        int low=0;
        int high=array.size()-1;
        while(low<high){
            if(array[low]+array[high]<sum) low++;
            else if(array[low]+array[high]>sum) high--;
            else{
                res.push_back(array[low]);
                res.push_back(array[high]);
                break;
            }
        }
        return res;
    }
};

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

输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。

 

解题思路:

设置两个指针,初始化第一个指向1,第二个指向2.

每次将两个指针包含所有元素相加得到SquSum:

  • 若SquSum小于sum,将第二个指针向后移一位。
  • 若SquSum大于sum,将第一个指针向后移一位。
class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> res;
        int start=1;
        int end=2;
        int SquSum=start+end;//维护一个和值
        while(start<=(sum+1)/2&&start<end){
            if(SquSum<sum) {
                end++;
                SquSum+=end;//第二个指针后移,和加上移动后的值
            }
            else if(SquSum>sum) {
                SquSum-=start;//第一个指针后移,但注意要先减去这个值,再后移。
                start++;
                
            }
            else{//找到了一个和值为sum的序列,保存,并将第二个指针后移一位继续找
                vector<int> squ;
                for(int i=start;i<=end;i++){
                    squ.push_back(i);
                }
                res.push_back(squ);
                end++;
                SquSum+=end;//第二个指针后移,和值加上移动后的值
            }
        }
        return res;
    }
};

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值