我老师教我Flash排序算法,费用约为O(n)。在运行那种排序之前,我必须找出数组中哪些元素是最大值和最小值。
这是我的解决方案:
//n is a size of array a[]
for(int i = 0; i < n ; i++){
if (_max < a[i]) _max = a[i];
if (_min > a[i]) _min = a[i];
}
令f(n)是for循环中的一些条件运算符(除了比较变量i)。所以费用:
所以,f(n)= 2n。
我的朋友写了这样的代码:
for(int i = 0; i < n-1; i+=2)
if (a[i] < a[i+1]){
if (_max < a[i+1]) _max = a[i+1];
if (_min > a[i]) _min = a[i];
}
else{
if (_max < a[i]) _max = a[i];
if (_min > a[i+1]) _min = a[i+1];
}
// Compare one more time if n is odd
if (n % 2 == 1){
if (_min > a[n-1]) _min = a[n-1];
if (_max < a[n-1]) _max = a[n-1];
}
我们可以很容易地得到f'(n)= 3n / 2 + 3.看来f'(n)&lt; f(n)当n足够大时。
但是我的老师要求f(n)= n或f(n)= n + a,a是一个const。
有什么想法吗?
答案 0 :(得分:1)
没有。在n(或n + a)个比较中,不可能找到最大值和最小值。它至少需要3n / 2 - 2次比较。请参阅this proof和this proof。也许你可以向老师展示这些证据......
关于序列还有其他提示吗?喜欢它是均匀分布的吗?
答案 1 :(得分:0)
当n
很大时,f&#39;(n)= f(n),因为两者都具有O(n)时间复杂度。
然而,似乎你需要找到min和max一次,所以你的算法具有时间复杂度O(n)是可以的,因为Flash Sort也花费O(n),因此整体时间复杂度将由为O(n)。
换句话说:
OverallTime = FindMinMax + FlashSort
OverallTime = O(n) + O(n)
OverallTime = 2*O(n)
OverallTime = O(n)
即使FindMinMax更快,Flash Sort的第二个词仍然会支配整体时间复杂度。
如果必须更快地执行此操作,您可以构建一个名为Segment Tree的数据结构,其中包含:
使用O(n log n)存储,可以在O(n log n)时间内构建。分割 树支持搜索包含查询的所有间隔 在O(log n + k)中指向,k是检索到的间隔的数量或 段。