【剑指offer】:和为s的两个数字&&和为s的连续正数序列

版权声明:本文为博主原创文章,欢迎转载,转载请声明出处! https://blog.csdn.net/hansionz/article/details/82693894
一.和为s的两个数字

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

解题思路:

  • 1.设置两个指针low,high,一个从数组最左边开始,一个从数组最右边开始
  • 2.比较low和high的和和s的大小
  • 3.如果low和high的和大于s,由于数组是递增有序的,所以要查找的俩个数必然在high指针的左边
  • 4.如果low和high的和小于s,由于数组是递增有序的,所以要查找的俩个数必然在high指针的右边
  • 5.相等则找到了,通过改变函数外的值输出
  • 6.当low等于high时,只剩一个数字,显然不可符合条件
    代码实现:
//1.给一个s和一个递增排序数组,输出数组中的任意两个和等于s的值
int GetSumMAndN(int *num, int len, int sum, int *m, int *n)
{
    assert(num&&m&&n);
    int low = 0;
    int high = len - 1;
    //low如果等于high,这时只有一个数了
    while (low < high)
    {
        if (num[low] + num[high]>sum)
            high--;
        else if (num[low] + num[high] < sum)
            low++;
        else
        {
            *m = num[low];
            *n = num[high];
            return 1;
        }
    }
    return 0;
}

二.和为s的连续正数序列

题目:输入一个正数s,打印出所以和为s的连续正数序列(至少含有两个数)。例如,输入15,则输出1 2 3 4 54 5 67 8

解题思路:本题目也是借助上边的思路来解决的。

  • 1.如果输入的s是小于等于3的,不存在至少含有两个数的和为s的连续正数序列
  • 2.从3开始,一直向右遍历,查找到small<mid既停止
  • 3.如果两个值都等于mid,必然不存在两个值中间的子数组和等于s
  • 4.所加值大于sum,必然要在小值这边移动
  • 5.所加值小于sum,在大值这边移动
  • 6.相等则输出,输出之后继续向后查找。

代码实现:

//2.给一个值s,输出所有和等于s的连续子数组
void FindContinousSeq(int sum)
{
    //给的和小于3,没有连续子数组,直接结束
    if (sum < 3)
        return;
    //sum>=3
    int small = 1;
    int big = 2;
    int mid = (sum + 1) / 2;
    int cur_sum = small + big;
    //整体思路是从左向右,依次查找

    //如果两个值都等于mid,必然不存在两个值中间的子数组和等于s
    while (small < mid)
    {
        if (cur_sum == sum)
        {
            PrintSeq(small, big);
        }
        //所加值大于sum,必然要在小值这边移动
        while (cur_sum>sum&&small < mid)
        {
            cur_sum -= small;
            small++;
            //将最小值减去在判断
            if (cur_sum == sum)
            {
                PrintSeq(small, big);
            }
        }
        //所加值小于sum,在大值这边移动
        big++;
        cur_sum += big;
    }
}

猜你喜欢

转载自blog.csdn.net/hansionz/article/details/82693894