第14 题:
题目:输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组1、2、4、7、11、15 和数字15。由于4+11=15,因此输出4 和11。
思路:
1、检测任意一个元素与其他n-1个元素之和,时间复杂度为O(n^2);
2、选择第一个元素a1与最后一个元素an, 假设输入的和为sum
如果a1 + an大于sum,说明我们需要将其中一个加数变小,a1无法再变小了,所以an->an-1
如果a1 + an小于sum,说明需要将加数变大,a1->a2
伪代码:
输入为 array[1...n], sum
head = 1;
tail = n;
while head <tail
do if array[head] + array[tail] > sum
tail <- tail - 1;
else if array[head] + array[tail] < sum
head<- head + 1;
else
// the numbers in index head , tail is what we want
代码:
#include <iostream>
#include <cassert>
#include <vector>
using namespace std;
void getSuitableNums(vector<int>sortedArray, int sum, int &a, int &b)
{
assert(sortedArray.size() > 1);
int head = 0;
int tail = sortedArray.size() - 1;
while( head < tail)
{
if (sortedArray[head] + sortedArray[tail] > sum)
{
tail--;
}
else if (sortedArray[head] + sortedArray[tail] < sum)
{
head++;
}
else
{
a = sortedArray[head];
b = sortedArray[tail];
break;
}
}
}
int main(void)
{
vector<int> sortedArray;
sortedArray.push_back(1);
sortedArray.push_back(2);
sortedArray.push_back(4);
sortedArray.push_back(7);
sortedArray.push_back(11);
sortedArray.push_back(15);
int sum = 15;
int a = 0;
int b = 0;
getSuitableNums(sortedArray, sum, a, b);
cout << a << " " << b << endl;
system("Pause");
return 0;
}