// 求数对之差的最大值.cpp : 定义控制台应用程序的入口点。
//
/*
直接算时间复杂度为O(n*n),分治算法时间复杂度为O(n*log(n)),此方法直接求解,时间复杂度为O(n),空间复杂度为1
思想:ofront表示第i次更新前的最大值,oback表示第i次更新前的最小值。nfront表示第i次更新后的最大值,nback表示第i次更新后的最小值。
ofront-oback表示原来球的最大差,用nfront表示一直到第i-1次之前的最大值,为什么记录最大值呢,因为若以后有比较小的数使原来的最大差值得到更新,一定是用前面的最大值减去那个较小的
数得到的差才是最大的。每当下一次更新时,两种可能条件 判断 1当a[i]>nfront时,更新记录的最大值,此时原来的ofront和oback不受影响;
2 当a[i]<nfront时,此时nfront-a[i]是一个还没求得差值,而且次差值有可能大于原来求得的差值,所以更新。
上面是自己想了两个小时 的结果。下面是 网上别人的想法:
2. 从右向左扫描数组,记录下遍历过程的最小值和差的最大值。
a. 当array[i]< min 时,min = array[i]
b. 当array[i]> min 时,计算diff = array[i] – min , maxdiff = MAX(maxdiff,diff)
遍历完数组时,即可得到书对之差的最大值
*/
#include "stdafx.h"
#include <iostream>
using namespace std;
#define N 8
int _tmain(int argc, _TCHAR* argv[])
{
int a[]={2,4,1,16,7,5,11,9};
int ofront,oback,nfront,nback;
ofront = a[0];//>a[1]?a[0]:a[1];
oback = a[0];//<a[1]?a[0]:a[1];
nfront=a[0];
int maxdiff=0;//=a[0]-a[1];
for (int i=1;i<N;i++)
{
if (nfront<a[i])
{
nfront=a[i];
}
else
{
nback=a[i];
//if (a[i]<oback)//
//{
if (nfront-nback>maxdiff)
{
maxdiff = nfront - nback;
ofront = nfront;
oback = nback;
}
//}
}
}
cout<<" max difference is "<<maxdiff<<" from "<<ofront<<" to "<<oback<<endl;
system("pause");
return 0;
}
这样的思路更好:
思路:假设f[i]表示数组中前i+1个数的解,前i+1个数的最大值为m[i]。则状态转移方程:
f[i] = max(f[i-1], m[i-1] - a[i]), m[i] = max(m[i-1],a[i])。问题的解为f[n-1]。