题目一:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得它们的和正好是S。如果有多对数字的和等于S,输出任意一对即可。例如:输入数组{1,2,4,7,11,15}和数字15,输出应该是4和11.
思路分析:看到这个题最开始我就想到了,从该数组的第一个数字开始固定数字,求该数字和其余的n-1个数字之和,找到S即可,但是这个方法的时间复杂度是O(n^2).
有一种简单的思想,我们可以定义连个指针,一个指针指向该数组的第一个元素(a),一个指针指向该数组的最后一个元素(b),有以下三步:
(1)当a+b=S时,返回a和b即可;
(2)当a+b>S时,b往前挪一个位置;
(3)当a+b<S时,a往前挪一个位置。
还是使用上述的例子,用下图来展示这样的一个过程:
代码实现如下:
1.
vector<int> FindNumbersWithSum(vector<int> array, int sum)
{
//先看类型,然后我们定义一个对应的值来作为返回值
vector<int> result;
int length = array.size();
if (length <= 1 || sum <= 0)
return result;
//a为数组的第一个数,b为数组的最后一个数
int a = 0;
int b = length - 1;
while (a<b)
{
int cursum = array[a] + array[b];
if (cursum == sum)
{
result.push_back(array[a]);
result.push_back(array[b]);
break;
}
else if (cursum>sum)
{
b--;
}
else
{
a++;
}
}
return result;
}
2.
bool FindNumbersWithSum(int data[], int length, int sum, int* num1, int* num2)
{
bool found = false;
if (length <= 1 || num1 == NULL || num2 == NULL)
return found;
int a = 0;//a在该数组的前面,从前往后
int b = length - 1;//b在该数组的最后面,从后往前
while (b > a)
{
int c = data[a] + data[b];
if (c == sum)
{
*num1 = data[a];
*num2 = data[b];
found = true;
break;
}
else if (c > sum)
{
b--;
}
else
{
a++;
}
}
return found;
}
题目二:输入一个整数S,打印出所有和为S的连续整数序列(至少含有两个数字)。例如:输入15,由于1+2+3+4+5=4+5+6=7+8=15,因此,打印的结果有三对1~5、4~6、7~8.
思路分析:这个题和上题有相似之处,我们可以定义连个数,一个为small,一个为big,标记第一个数和第二个数,同样有以下三种情况:
(1)当该序列的和等于S时,将该连续序列打印出来;
(2)当该序列的和大于S时,big++;
(3)当该序列的和小于S时,small++.
说明:可能有人会问,那这个题的循环条件结束是什么呢?我们以S为15举例,和为S 的最大连续序列为7和8,也就是说8之后和为S 没有连续的序列了,因此,类比,可以知道,该循环结束的标志是small=(1+S)/2
下面我们用代码实现:
1.
vector<vector<int> > FindContinuousSequence(int sum)
{
vector<vector<int> > result;
if(sum<3)
return result;
int small=1;
int big=2;
int mid=(1+sum)/2;
while(small<mid)
{
int cursum = 0;
for(int i = small; i <= big; i++)
{
cursum += i;
}
if(cursum == sum)
{
vector<int> v;
for(int i = small; i <= big; i++)
{
v.push_back(i);
}
result.push_back(v);
small++;
big++;
}
else if(cursum < sum)
{
big++;
}
else
{
small++;
}
}
return result;
}
2.
void PrintSequence(int small, int big)
{
for (int i = small; i <= big; i++)
{
cout << i;
}
cout << endl;
}
void FindSequence(int sum)
{
if (sum <= 2)
return;
int small = 1;
int big = 2;
int mid = (1 + sum) / 2;
int cursum = small + big;
while (small < mid)
{
if (cursum == sum)
PrintSequence(small, big);
if (cursum > sum && small < mid)
{
cursum -= small;
small++;
if (cursum==sum)
PrintSequence(small, big);
}
else
{
big++;
cursum += big;
}
}
}
int main()
{
int s = 15;
int length = (s + 1) / 2;
int *arr = new int[length];
for (int i = 0; i < length-1; i++)
{
arr[i] = i + 1;
}
FindSequence( s);
delete[] arr;
cout << endl;
return 0;
}
注意:当cursum>S时,先big++,然后再计算cursum的值;当cursum<S时,先计算cursum的值,再small++!