请考虑以下代码片段。假设A [0 ... n]是一个数组,其元素是0到n之间的自然数

时间:2017-01-23 23:22:12

标签: algorithm

我在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,我认为如果条件不满意,最低执行量可能为零,但不确定如何继续执行。

我对两个部分都不确定,非常感谢解释/帮助。

1 个答案:

答案 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)。通常这会以更加数学的方式表达,但由于我并不完全是乳胶专业人士,所以你必须自己考虑总和 -