我正在从代码解决problem。根据editorial,以下代码的复杂度应该是O(n)。如何分析这段代码的复杂性?
for(int i = n - 1; i >= 0; --i) {
r[i] = i + 1;
while (r[i] < n && height[i] > height[r[i]])
r[i] = r[r[i]];
if (r[i] < n && height[i] == height[r[i]])
r[i] = r[r[i]];
}
这里,height[i]
是i
个山的高度和r[i]
是第一右山比height[i]
更高的位置,并且是height[0]
高度阵列的其它值中的最大的总。
我的问题是,我们如何保证代码的复杂性是O(n),虽然内部while循环的存在?
在inner while循环中,代码更新r[i]
值,直到height[i]
>height[r[i]]
。并且更新的数量取决于高度数组。例如,按非递减顺序排列的高度数组的更新次数将与按非递增顺序排列的高度数组的排列次数不同。 (在这两种情况下,我们将排列除height[0]
之外的数组,因为height[0]
在此问题中应始终为最大值)。
是否有任何方法来分析这样的输入数据变化的算法?摊销分析将是答案之一?
PS。我想更多地阐明我的问题,我们要在循环中设置数组r []。那这个呢?如果数组height = {5,4,1,2,3}
和i=1
,(r[2]=3
,r[3]=4
,因为2是第一个大于1的值,而3是第一个大于2的值),我们将4与1进行比较,并且因为4> 1,我们继续试图比较4和2(= height[r[2]]
),4与3(= height[r[3]]
)。在这种情况下,我们必须比较4次来设置r [1]。比较次数与height = {5,1,2,3,4}
不同。我们仍然可以保证代码的复杂性是O(n)吗?如果我错过了什么,请让我知道。谢谢。