数组最大差值问题

给定一个整数数组,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;
}
}
}

转载于:https://www.cnblogs.com/kevinLee-xjtu/archive/2011/12/14/2299087.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值