剑指offer-和为s的两个数VS和为s的正整数序列


/*******************************************************************
Copyright(c) 2016, Tyrone Li
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//
 
/*
Q1:
    和为s的两个数字:
        输入一个递增排序的数组和一个数字,在数组中找到两个数,使得他们的和
        刚好为输入的数字;如果有多对数字的和等于该数字,那么输出任意一对即可。
S1:
    1. 在数组中随机指向两个数,如果这两个数之和大于输入的数字,那么考虑在后面
       一个比较大的数字上,将其往前挪,好让两者之和小一点;如果比输入的数字小,
       那么可以考虑将前面那个数字往后挪一下,好让两者之和大一点。

Q2:
    和为s的连续正整数序列:
        输入一个正整数s,打印出所有的和为s的连续正整数序列(至少含有两个数)。
        例如:
            输入:15
            输出:{1,2,3,4,5} [4,5,6] {7,8}
S2:
    1. 借鉴题目一的思路,初始化两个数,一个是1,另一个是2,如果该序列之和小于s,
       那么可以考虑加入更大的数,也就是第二个指针往前挪;如果该序列之和大于s,那
       么可以考虑去掉最小的数,也就是第一个指针往前挪。
*/
 
#include <iostream>
#include <cstdio>
#include <cstdlib>

void getSumOfNumPair(int*data, int length, long sum, int*num_1, int*num_2)
{
    if(data == nullptr || length <= 0)
        return;
    
    int pAhead = 0;
    int pBehind = length - 1;

    while(pAhead < pBehind)
    {
        if(sum == (data[pAhead] + data[pBehind]))
        {
            *num_1 = pAhead;
            *num_2 = pBehind;
            break;
        }else if(sum < (data[pAhead] + data[pBehind]))
        {
            pBehind--;
        }else{
            pAhead++;
        }
    }
}

void printLists(long small, long big)
{
    for(long i = small; i <= big; ++i)
        std::cout << i << " ";
    std::cout << std::endl;
}

void getSumOfNumLists(long sum)
{
    if(sum < 3)
        return;
    
    long small = 1;
    long big = 2;
    long curSum = small + big;
    long mid = (1 + sum) / 2;
    while(small < mid)
    {
        if(curSum == sum)
        {
            printLists(small, big);
        }

        while(curSum > sum && small < mid)
        {
            curSum -= small;
            small++;

            if(curSum == sum)
            {
                printLists(small, big);
            }
        }

        big++;
        curSum += big;
    }

}

void test_1()
{
    std::cout << "Test 1" << std::endl;
    int data[] = {1,2,3,4,5,6,7,8,9,10};
    for(auto e:data)
        std::cout << e << " ";
    std::cout << std::endl;

    int num_1 = 0;
    int num_2 = 0;
    getSumOfNumPair(data, 10, 17, &num_1, &num_2);
    std::cout << "sum : " << 17 << " num_1 : " << num_1 << " num_2 : " << num_2 << std::endl;
    getSumOfNumLists(15);
}

void test_2()
{
    std::cout << "Test 2" << std::endl;
    int data[] = {1,2,3,4,5,6,7,8,9,10};
    for(auto e:data)
        std::cout << e << " ";
    std::cout << std::endl;

    int num_1 = 0;
    int num_2 = 0;
    getSumOfNumPair(data, 10, 20, &num_1, &num_2);
    std::cout << "sum : " << 17 << " num_1 : " << num_1 << " num_2 : " << num_2 << std::endl;
    getSumOfNumLists(99);
}

void test_3()
{
    std::cout << "Test 3" << std::endl;
    int*data = nullptr;

    int num_1 = 0;
    int num_2 = 0;
    getSumOfNumPair(data, 0, 20, &num_1, &num_2);
    std::cout << "sum : " << 17 << " num_1 : " << num_1 << " num_2 : " << num_2 << std::endl;
    getSumOfNumLists(20);
}

void test_getSumOfNumPair()
{
    test_1();
    test_2();
    test_3();
}

int main(int argc, char**argv)
{

    test_getSumOfNumPair();

    return 0;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值