求无序数组的(max+min)最大的子数组------为学论坛上面的一道面试题

来源:互联网 发布:php拆分gif 编辑:程序博客网 时间:2024/04/29 21:02

原题目链接:http://www.51weixue.com/thread-398-1-1.html

题目:

杭州某公司的面试题,哪家可自己猜,不方便说;算是其中挺难的题了,当场能做出来的极少;出出来为论坛增点人气!

求无序数组的(max+min)最大的子数组

题目意思就是,给出一个无序的数组,均为正数,要找一个子数组,使得该子数组内的最小值加上最大值能取到最大。
例子:        3 9 2 7 1 5 8
能取到的(max+min)最大的子数组为(5,8)。

-------------------------------分割线------------------------

粗略一看,能够想出时间复杂度为O(n^2)的算法并不难,无非就是遍历所有子数组,并找出其中最小值+最大值为最大的那个。但是能不能够找到时间复杂度为O(n)的算法呢?

刚开始想的时候,自己还真没有想到有什么简便的方法,老是往一种复杂的地方去想。其实只要写多几组示例数据就能够找出其中的规律。

 

例如:

示例一:3 9 2 7 1 5 8,最大为(5,8),

示例二:6 5 10 9 4 11,最大为(10,9)

示例三:4 7 3 7 9 2 7 ,最大为(7,9)

示例四:4 9 10 5 11 4 7 9,最大为(9,10)

------------------------------

看出其中的规律没?有没有发现其中最大的子数组都是由两个元素组成的?既然这样,我就先YY这个符合条件的子数组必然是由两个元素组成的。那么去推敲一下。

首先,一开始有两个元素,其中一个为最大值,一个为最小值。然后引入第三个元素,如果这第三个元素比刚才那两个更大,那么我们可以建立一个新的符合条件的子数组。比如示例二中一开始子数组为(6,5),最大值为6,最小值为5,引入第三个元素10后,则符合条件最大的子数组变为(5,10)。同样道理,当引第三个元素比刚才那两个元素都更小时我们,则最大的子数组由刚才那两个元素组成。比如示例三中,(4,7,3).

那么,根据这个规律,我们便可以很轻松地写出一个时间复杂度为O(n)的算法。

 

 代码实现:

#include<stdio.h>const int N = 100 ;int A[N] ;int FindMaxSum(int *ptrA,int n) ; int main(void){int i,n ;freopen("in.txt","r",stdin) ;while(scanf("%d",&n) != EOF){for(i = 0 ; i < n ; ++i){scanf("%d",&A[i]) ;}printf("%d\n",FindMaxSum(A,n)) ;}return 0 ;}int FindMaxSum(int *ptrA,int n) {int i,nTemp,nMaxSum = 0 ;for(i = 0 ; i < n ; ++i){if(i+1 < n){nTemp = ptrA[i] + ptrA[i+1] ;if(nTemp > nMaxSum){nMaxSum = nTemp ;}}}if(1 == n) //对应数组元素只有一个的情况{nMaxSum = ptrA[0] ; }return nMaxSum ;}


 

原创粉丝点击