算法习题14:输入一个已经按升序排序过的数组和一个数字

来源:互联网 发布:ping服务器的某个端口 编辑:程序博客网 时间:2024/04/29 08:25

原题:

题目:输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是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 50void 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;elsearr[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--;}}}