题目
读题
求第i个数右侧的最大值,就需要求出在(i,n-1]之间的最大值,并把这个最大值赋给arr[i],
求解问题便变成了求左开右闭后缀最大值的问题
运用动态规划
设计状态:求第i项之后的最大值(包含第1项)就转移到求[第i+1项之后的最大值(包含第i+1项)和第i项之间]的最大值
写出状态方程:Rmix[i]=max(Rmix[i+1],a[i]);
设定初始状态:Rmix[n-1]=a[n-1]; rmix[n-1]=-1;
执行状态转移
返回最终解
注意事项
“Note: The returned array must be malloced, assume caller calls free().”
1 - 返回的数组需要分配空间,不是在原来的数组上修改,但是函数在调用此函数时会帮我们释放分配的空间
2 - 返回数组的大小
代码段
int max(int a,int b) //定义一个求最大值的函数
{
return a>b?a:b;
}
void RMix(int* a,int n,int* Rmix) //定义一个求第i项之后的最大值(包含第i项)的函数
{
int i;
for(i=n-1;i>=0;i--)
{
if(i==n-1)
{
Rmix[i]=a[i];
}
else
{
Rmix[i]=max(Rmix[i+1],a[i]);
}
}
}
#define MAXN 10005
int* replaceElements(int* arr, int arrSize, int* returnSize){
int i;
int postMax[MAXN]; //定义一个存放最大值的数组
int* rmix=(int *)malloc(sizeof(int) *arrSize); //定义一个返回数组
*returnSize=arrSize; //这点要注意!返回数组大小
RMix(arr,arrSize,postMax);
for(i=0;i<arrSize;i++)
{
if(i==arrSize-1)
{
rmix[i]=-1; //最后一项的值修改为 -1
}
else
{
rmix[i]=postMax[i+1];
}
}
return rmix;
}
执行结果
时间复杂度和空间分析:
代码共执行2n次,因此时间复杂度为O(n)
分配了两个数组,因此空间复杂度为O(n)
总结
1 - 动态分配内存
2 - 万变不离其宗:剖析问题最底层,发现是求解后缀最大值的问题,运用状态转移求解
3 - 读清要求:新建数组存放结果,而不是在原数组作修改