O(N *日志(日志(N)))算法Codility的高峰?日志、算法、高峰、Codility

2023-09-11 06:29:18 作者:撈資比妳媽 還愛妳

介绍的任务是在这里: https://codility.com/demo/take-样品测​​试/峰的 这也是在这里: Codility峰复杂

The task description is here: https://codility.com/demo/take-sample-test/peaks It's also here: Codility Peaks Complexity

首先,我想解决这个自己,但也仅仅能拿出什么,我认为是一个强力的解决方案。然而,它取得了100/100: https://codility.com/demo/results/demoRNWC3P-X4U

First, I tried solving this myself but was only able to come up with what I believed to be a brute force solution. However, it scored 100/100: https://codility.com/demo/results/demoRNWC3P-X4U

这显然是完全不满意我。 ;)外环是呼吁 N (或者每个峰值,较小者为准)及内一个被称为每个峰(只检查,如果有一个各因素在每块峰值)。也许这就是 O(N ^ 2),也许会好一点(因为它传递的时间限制的测试),但我几乎可以肯定这不是 O(N *日志(日志(N)))

Which obviously is completely unsatisfying for me. ;) The outer loop is called for each factor of N (or for each peak, whichever is smaller) and the inner one is called for each peak (just checking if there's a peak in every block). Maybe that's O(N^2), maybe a bit better (since it passes the tests in time limits) but I'm almost sure it's not O(N*log(log(N))).

然后我试图寻找一个 O(N *日志(日志(N)))解决方案,但其他人似乎有一个pretty的类似解决方案,以矿

Then I tried searching for an O(N*log(log(N))) solution but everyone else seems to have a pretty similar solution to mine.

因此​​,没有人有一个想法,一个 O(N *日志(日志(N))) (或更好的)解决方案?

So does anyone have an idea for an O(N*log(log(N))) (or a better one) solution?

此外,如果有人能告诉我什么复杂我的解决方案有,我会感激不尽。的

推荐答案

您code是O(ND(N)),其中d(n)为n个约数的数量。上[1,100000],D(n)被最大化以83160 = 2 ^ 3 3 ^ 3 5 7 11,其具有126的除数。 根据维基百科,D(N)是O(n ^小量),每小量> 0,所以它的增长相当缓慢。

Your code is O(n d(n)) where d(n) is the number of divisors of n. On [1, 100000], d(n) is maximised at 83160 = 2^3 3^3 5 7 11, which has 126 divisors. According to Wikipedia, d(n) is o(n^epsilon) for every epsilon>0, so it grows rather slowly.

要获得O(N日志log n)的解决方案,打造一个部分和数组告诉你有多少山峰留下每一个点。然后你就可以判断是否有在O(1)时间间隔的峰值。检查一个数D则需要O(N / D)的时间。加起来N / D超过所有分频器d是相同加起来ð在所有除数D,并且其结果是,根据同一Wikipedia页面,为O(n日志log n)的

To get an O(n log log n) solution, build a partial sum array telling you how many peaks are left of each point. Then you can tell whether there's a peak in an interval in O(1) time. Checking a divisor d then takes O(n/d) time. Adding up n/d over all divisors d is the same as adding up d over all divisors d, and the result is, according to the same Wikipedia page, O(n log log n).