云淡风轻
Stay foolish,stay hungry.
给定一个整数数组,a[1],a[2],...,a[n],每一个元素a[i]可以和它右边的(a[i+1],a[i+2],...,a[n])元素做差,求这个数组中最大的差值,例如a={0,3,9,1,3,5}这个数组最大的差值就是9-1=8;
解答:
1)这个题目最直接的想法就是穷举,时间代价是O(n^2),即检查每个元素与其右边元素差值的最大值,伪代码如下:
int solve_sub(int *a,int n)
{
int max=INT_MIN;
for(int i=n-1;i>=1;i++)
{
for(int j=i+1;j<=n;j++)
{
if(a[i]-a[j]>max)
max=a[i]-a[j];
}
}
return max;
}
2)下面给出一个O(n)复杂度的算法,利用DP的思想,定义S[i]为a[i]与其右边元素之差的最大值,那么状态转移方程为:
s[i]=a[i]-a[i+1]      if s[i+1]<0   (表明a[i+1]是从i+1到n所有元素中最小的一个)
s[i]=s[i+1]+a[i]-a[i+1]  if s[i+1]>=0  
初始情况为s[n]=0,伪代码如下:
//求数组元素与其右边元素做差,差值的最大值时间o(n)空间O(n)
void sovle_maxSub_Dp(int *a, int n){
int *S=new int[n+1]();
int max_value=INT_MIN;
int max_index=0;
for(int i=n-1;i>=1;i--){
S[i]=S[i+1]<0?a[i]-a[i+1]:a[i]-a[i+1]+S[i+1];
if(max_value<S[i]){
max_value=S[i];
max_index=i;
}
}
cout<<"最大差值为:"<<max_value<<",对应的两个元素为:"<<endl;
cout<<"数组中第"<<max_index<<"个元素:"<<a[max_index]<<endl;
for(int i=max_index+1;i<=n;i++){
if(a[max_index]-a[i]==max_value){
cout<<"数组中第"<<i<<"个元素:"<<a[i]<<endl;
break;
}
}
}
同最长递增/递减子序列的问题解法类似,这个题目的空间还可以优化为O(1),因为当前S[i]只依赖于其后面的S[i+1],我们只用一个变量S即可表示当前的状态,循环从i=n-1 to 1,初始状态就是S=S[n] 不断更新这个状态即可,代码如下:
//求数组元素与其右边元素做差,差值的最大值时间o(n)空间O(1)
void sovle_maxSub_Dp_OptimalSpace(int *a, int n){
int S=0;
int max_value=INT_MIN;
int max_index=0;
for(int i=n-1;i>=1;i--){
S=S<0?a[i]-a[i+1]:a[i]-a[i+1]+S;
if(max_value<S){
max_value=S;
max_index=i;
}
}
cout<<"最大差值为:"<<max_value<<",对应的两个元素为:"<<endl;
cout<<"数组中第"<<max_index<<"个元素:"<<a[max_index]<<endl;
for(int i=max_index+1;i<=n;i++){
if(a[max_index]-a[i]==max_value){
cout<<"数组中第"<<i<<"个元素:"<<a[i]<<endl;
break;
}
}
}
posted on 2011-12-14 10:42  kevin Lee  阅读(3411)  评论(1编辑  收藏  举报