下周我有决赛即将开始,而且我正在尝试学习旧笔记和作业/考试。在我的第二个家庭作业中,我有一个问题,我错了,我只是不确定究竟要做什么。这是问题所在:
设计有效算法,采用一组正数'a',并确定: 一个。 a [j] + a [i]的最大值,其中j>或者=我。 湾a [j] - a [i]的最大值,其中j>或=到我。
我不想要实际代码,只需要一些伪代码及其运行时间。
我认为会起作用:
找到第一,第二和第三个最大值和最小值。 然后做: 一个。对于j> = i,第一最大a(j)+第二最大a(i)。 湾first max a(j) - first min a(i),j> = i
如果上述条件失败,则以第二个最大值,最小值重复。
我不知道为什么我无法绕过这个。我知道j可以等于i,所以我的答案会产生a部分的错误结果。对于b部分,假设我有一个数组[89 | 90 | 1 | 2 | 3 | 4 | 5],它会变为90 - 1 = 89但它应该是5 - 1 = 4.我甚至没有尝试过因为那部分是错误的,所以要考虑运行时间。
任何帮助或提示都会很棒。谢谢!
答案 0 :(得分:1)
一个。 a [j] + a [i]是直接的,它只有2 *,因为j可以等于我可以在O(N)
中完成
湾a [j] - a [i]对于这种情况,我们需要一些动态编程才能在O(N)中得到它。这是在O(N)中执行此操作的方法: -
构建一个数组,使得max [i]表示子数组中的最大元素a [i to n]
max[n] = a[n]
for(i=n-1;i>=1;i--)
max[i] = maximum(max[i+1],a[i]);
然后为您(max[i]-a[i])
的所有i找到最大值max a[j]-a[i]
。
编辑:刚刚意识到不需要维护数组max []你可以计算max [i] - a [i],同时使用之前的值来评估max [i]。
答案 1 :(得分:1)
一个。最大a [i] + a [j]是找到数组中的最大和第二大值,它很简单,时间复杂度为O(N)。
湾为了最大化a [j] -a [i](j> = i),对于每个j,可能的最优解是a [j] - j之前的最小值,所以你只需要保持这个值并更新最好的溶液
mmin = a[0];
ans = 0;
for (int j = 0; j < length(a); ++j){
mmin = min(a[j], mmin);
ans = max(ans, a[j] - mmin);
}
return ans;
它也是O(N)。