我在stackoverflow中的第一篇文章,我对这个关于算法的问题遇到了麻烦。
考虑以下代码片段。假设A [0 ... n]是一个数组,其元素是0到n之间的自然数。
for i=0 to n-1 do {
for j=n-i-1 to 0 do{
if(A[j] <= A[j+1]){
print A[j]-A[j+1];
}
}
}
(a)作为n的函数,print语句可能的最大次数是多少 执行? A中的条目模式是什么导致了这种最坏的情况?将您的答案表达为求和,然后将此求和的解决方案表达为精确(非渐近) 公式涉及n。
(b)作为n的函数,输出语句可能执行的最小次数是多少? A中的条目模式是什么导致这种最佳情况?对于这部分,你可以 渐渐地表达你的答案。
对于A,我的条目模式为1,2,3,...,n-1
给我f-(n-1)+(n-2)+ ... + 1 = O(n ^ 2)
对于B,我认为如果条件不满意,最低执行量可能为零,但不确定如何继续执行。
我对两个部分都不确定,非常感谢解释/帮助。
答案 0 :(得分:2)
这段代码是我们确定何时执行print语句所需要的部分:
if(A[j] <= A[j+1]){
print A[j]-A[j+1];
}
因此,每当遇到两个连续的值时,将执行print语句,使得索引较小的值小于索引较大的值。因此,对于任何递增排序的数组,如果从未按顺序排序,则将为每个j
执行print语句。
与数组的规格一起,这将导致数组
worstcase = [0, 1, 2, ..., n]
bestcase = [n, n-1, n-2, ..., 0]
现在,在最坏的情况下,print语句将始终执行,所以:
result = 0;
for i=0 to n-1 do {
for j=n-i-1 to 0 do{
result += 1;
}
}
(result
计算执行打印的次数),这显然相当于:
result = 0;
for i=0 to n-1 do {
result += n - i;
}
或者
result = 0;
for i=1 to n do{
result += i;
}
所以result = (n + 1)*n/2
O(n^2)
。
现在在最坏的情况下,我们可以应用相同的模式:
result = 0;
for i=0 to n-1 do {
for j=n-i-1 to 0 do{
result += 0;
}
}
显然可以减少到result = 0
,即O(1)
。通常这会以更加数学的方式表达,但由于我并不完全是乳胶专业人士,所以你必须自己考虑总和 -