和为s的两个数字 VS 和为s的连续正数序列42

本文介绍两种算法:一种是在递增排序数组中寻找两数之和等于给定值的方法;另一种是找出所有连续正整数序列,其和等于给定正数。文章通过示例展示了算法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。例如输入数组{1, 2, 4, 7, 11, 15}和数字15。由于4 + 11 = 15,因此输出4和11。

解题思路:

  1. 先在数组中选择两个数(第一个数和最后一个数),如果它们的和等于输入的s,那么就找到了数字。
  2. 如果小于s,由于数组是递增排序的,所以可以选择将第一个数字递增到下一个数字。
  3. 如果大于s,可以将最后一个数字递减到前一个数字
  4. 依次不断查找

测试用例:

int main(){
    //输入数组
    int arr[6] = {1, 2, 4, 7, 11, 15};
    //找到的两个数字
    int num1 = 0, num2 = 0;
    int s = 15;
    //执行查找和为s的两个数字
    if( FindNumbersWithSum(arr, 6, s, &num1, &num2) )
        std::cout << num1 << " + " << num2 << " = " << s;
    else
        std::cout << "Not found!\n";

    return 0;
}

函数实现:

//查找和为s的两个数字
bool FindNumbersWithSum(int data[], int length, int sum, int *num1, int *num2){
    bool found = false;
    if(data == NULL || length < 1 || num1 == NULL || num2 == NULL)
        return found;
    //“第一个数字”
    int ahead =  0;
    //“最后一个数字”
    int behind = length - 1;
    //循环查找
    while(behind > ahead){
        //当前和
        long long curSum = data[ahead] + data[behind];
        if(curSum == sum){
            *num1 = data[ahead];
            *num2 = data[behind];
            found = true;
            break;
        }else if(curSum > sum)
            behind--;
        else
            ahead++;
    }

    return found;
}

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

解题思路:

  1. 使用small和big分别表示序列的最小值和最大值。
  2. 如果small到big的序列大于s,去掉序列中较小的值,即增大small。
  3. 如果small到big的序列小于s,去掉序列中较大的值,即增大big。
  4. 因为序列至少两个数字,我们一直增加small到(1+s) / 2为止。

测试用例:

//测试用例
int main(){
    //输入正数
    int sum = 15;
    //打印所有和为s的正数序列
    FindContinuousSequence(sum);  //Output: 1 2 3 4 5 和 4 5 6 和 7 8

    return 0;
}

函数实现:

//打印函数
void PrintContinuousSequenve(int small, int big){
    for(int i = small; i <= big; ++i)
        std::cout << i << " ";
    std::cout << std::endl;
}
//主函数
void FindContinuousSequence(int sum){
    if(sum < 3)
        return;
    int small = 1;
    int big = 2;
    //循环终止的条件
    int middle = (1 + sum) / 2;
    int curSum = small + big;

    while(small < middle){
        if(curSum == sum)
            PrintContinuousSequenve(small, big);
        while(curSum > sum && small < middle){ //如果当前和大于s,增大small,否则--
            curSum -= small; //去掉较小的值
            small++;
            if(curSum == sum)
                PrintContinuousSequenve(small, big);
        }
        //--否则直接增大big
        big++;
        curSum += big;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值