预期的Previous Larger Element算法的运行时间

时间:2013-09-29 10:01:12

标签: algorithm probability

以下算法返回数组的上一个较大元素。它来自these笔记的第11页。

// Input: An array of numeric values a[1..n]
// Returns: An array p[1..n] where p[i] contains the index of the previous
// larger element to a[i], or 0 if no such element exists.
previousLarger(a[1..n]) 
    for (i = 1 to n)
        j = i-1;
        while (j > 0 and a[j] <= a[i]) j--;
        p[i] = j;
return p

我的作业问题是:鉴于输入序列{a1,...,an}是集合{1,...,n}的随机排列,预计运行时间是多少?

我认为这需要某种概率分析,但我需要一些提示,因为我过去只进行过最坏情况分析。我正在尝试找到给定i的j-loop成本的公式(1 +我们操作的次数j--),然后将该公式从1加到n。

“预期”是什么意思?我真的不知道如何解释这个。

2 个答案:

答案 0 :(得分:1)

以@Heuster的答案为基础:

1)你知道答案是在O(n)和O(n ^ 2)之间。这只是为了检查最终结果。

2)元素i的预期步数确实是:

sum_{k=1}^i 1 / (k+1)
= O(log i)

3)你必须将所有这些数字加在i上。这给你:

sum_{i=1}^n O(log i)
= O(n log n)

我所做的并不严谨,但你可以证明它是衍生出来的。 O(n log n)介于O(n)和O(n ^ 2)之间,因此它似乎是一个很好的候选者:)

答案 1 :(得分:0)

对于和任意索引ia[i-1] > a[i](换句话说,内部while循环将采取一步)的可能性是多少?这很容易:a中的所有元素都不同,所以P(a[i-1] > a[i]) = P(a[i] > a[i-1]) = 1/2

现在,看一下内部while循环需要采取两个步骤的情况。也就是a[i-2] > a[i] > a[i-1]。这正是3个元素的6个排列中的一个,因此机会为1 / 3! = 1 / 6

让我们概括一下,并假设内部while循环需要采取k步。我们考虑子列表a[i-k], a[i-k+1], ..., a[i]。我们知道a[i-k]是此子列表的最大元素,a[i]是第二大(否则,内循环会更快停止)。中间元素的顺序是无关紧要的。因此,我们采取k步骤的可能性为1 / (k + 1) * 1 / k = 1 / (k * (k + 1))。请注意,1/2的{​​{1}}和k = 1 1/6的确为k = 2

a[i]之前没有任何元素增加的可能性只是1 / ia[i]是该子列表中的最大元素)。在这种情况下,内循环需要i步。

元素i的预期步数是(概率乘以值的总和):

Sum[{k, 1, i} k * 1 / ((k * (k + 1))] + i / i 
    = Sum[{k, 1, i} 1 / (k + 1)] + 1
    = H_{i+1}

其中H_{i}是第i个谐波数,它是log i的离散变量。也就是说,元素i的步数为Θ(i)

现在剩下的是对所有i求和以找到预期的运行时间。如果使用精确值(H_{i+1}),则无法获得良好的表达式,请参阅Wolfram Alpha

然而,标准的继续方法是继续使用近似的log i。显然,log 0 + log 1 + ... + log n-1小于n log n。现在,考虑总和的后半部分:

log n/2 + log n/2+1 + ... + log n-1 > n/2 log n/2
                                    = n/2 (log n - log 2)
                                    = Ω(n log n)

因此,预计的运行时间为Θ(n log n)