版权声明:本文为博主原创文章,欢迎转载,转载请声明出处! 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 5
和4 5 6
和7 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;
}
}