在看《算法问题实战策略》这本书的时候,遇到了一个问题:平均移动,这个问题类似于区间问题,找出区间的两个端点,然后再进行操作
1.n个数据找出M个月的平均移动
1)时间复杂度O(n^2)
vector<double>movingAverage1(const vector<double>&A, int M)//时间复杂度O(N^2)
{
vector<double>ret;
int N = A.size();
for (int i = M - 1; i < N; i++)//右区间
{
double sum = 0.0;
for (int j = 0; j < M; j++)//左区间
{
sum += A[i - j];//index[右区间-左区间],保证区间长度为M
}
ret.push_back(sum / M);
}
return ret;//一共返回(n-m+1)个数据
}
分析:
多了一些重复的数据:主要体现在:我们仅仅需要找到左区间和右区间点,然后将左右区间点之间的数字相加即可,并不需要遍历其余的数字,例如:A[M+1],仅仅需要找到左区间A[2],然后用O(n)的复杂度从A[2]+A[3]+...A[M+1],也就是第二种时间复杂度为O(N)的思想
2)时间复杂度O(N)
vector<double>movingAverage2(const vector<double>&A, int M)
{
vector<double>ret;
int N = A.size();
double sum = 0.0;
for (int i = 0; i < M; i++)//前m个数据不能进行移动平均
{
sum += A[i];
}
for (int i = M - 1; i < N; i++)
{
sum += A[i];//右区间向右移动
ret.push_back(sum / M);//求出移动平均值
sum -= A[i - (M - 1)];//i-(M-1)表示左区间,sum此时是整个N个数字的总和,需要进行减去左区间来使得左区间向右移动
}
return ret;//一共返回(n-m+1)个数据
}