原题:
题目:输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。
---------------------------
但其是这道题如果考官再拿来考,应该会改成
输入一串数字以及一个和,从这串数字里找出和为这个值的一对数字?如果要找出所有的呢?
-----------------------------------
所以这道题就需要先进行排序,然后求和,而排序又涉及到了多种算法,是采用O(NlogN)的算法还是O(N^2),排序又有那几种常用算法呢?
排序算法我有总结了下:一般都用快速排序,堆排序,归并排序,插入排序,希尔排序,选择排序,冒泡排序等等
大家可以参见:http://blog.csdn.net/ylf13/article/details/12651117 我的这篇博文,不过还在补充中,内容不足还请谅解,其他算法大家可以再去了解了解
回到这题,需要时间复杂度O(n)看来是不能找出所有组合来得出结果了,但是我们发现,数据是排列好的,这就是说如果a[i]+a[j]>sum
假设a[i]>a[j],i 和j 分别是数组尾和数组头部两个Index,那么就需要i--如下(j++只会让结果更大)
2 4 6 8 9 10 16 15
j i
2 4 6 8 9 10 16 15
j i
这时候发现2 + 10 < 15 所以j++
2 4 6 8 9 10 16 15
j i
4+10<15 j++2 4 6 8 9 10 16 15
j i
6+10>15 i--
2 4 6 8 9 10 16 15
j i
6+9 = 15 找到了!!
--------------------------
而且这个过程o(N)
问题再深度点,如果要找出所有和为15的呢?这就需要继续往下找,我给出了下面程序,同时避免输出同样的结果例如 1 1 1 4 5
这样只输出1+4=5
//============================================================================
// Name : FindSumFactor.cpp
// Author : YLF
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
using namespace std;
#define MAX 50
void findFactor(int *arr, int num, int sum);
int main() {
int arr[MAX];
int input = 0;
int num = -1;
int sum = 0;
while(true){
num++;
cin>>input;
if(input == -1)
break;
else
arr[num] = input;
}
sum = arr[--num];
findFactor(arr, num, sum);
return 0;
}
void findFactor(int *arr, int num, int sum){
int i = num-1;
int j = 0;
int temp = -1;
while(i > j){
if(arr[i] + arr[j] > sum)
i--;
else if(arr[i] + arr[j] < sum)
j++;
else{
if(temp == arr[j] || temp == arr[i]){
//这个判断是去重复
i--;
continue;
}
cout<<arr[j]<<"+"<<arr[i]<<"="<<sum<<endl;
temp = arr[i];
i--;
}
}
}