首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >O(N*log(log(N)算法?

O(N*log(log(N)算法?
EN

Stack Overflow用户
提问于 2014-10-01 20:38:03
回答 2查看 1.4K关注 0票数 1

任务描述在这里:https://codility.com/demo/take-sample-test/peaks也在这里:谦卑高峰复杂性

首先,我试着自己解决这个问题,但是我只想出了一个我认为是蛮力的解决方案。然而,它的得分是100分:https://codility.com/demo/results/demoRNWC3P-X4U

显然我完全不满意。)对N的每个因子(或每个峰值,以较小的值为准)调用外部循环,对每个峰值调用内部循环(只需检查每个块中是否有一个峰值)。也许这是O(N^2),也许更好一些(因为它在时间限制内通过了测试),但我几乎可以肯定它不是O(N*log(log(N)))

然后,我尝试寻找一个O(N*log(log(N)))解决方案,但其他人似乎都有一个与我的解决方案非常相似的解决方案。

那么,是否有人对O(N*log(log(N))) (或更好的)解决方案有一个想法?

而且,如果有人能告诉我我的解决方案有多复杂,我会很感激的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-01 21:24:26

您的代码是O(n ( n )),其中d(n)是n的除数,在1,100000上,d(n)在83160 = 2^ 3 ^3 ^3 5 7 11时最大,其中有126个除数。根据维基百科,d(n)对于每一个epsilon>0都是o(n^epsilon),所以生长得相当慢。

要获得O(n日志日志n)解决方案,请构建一个部分和数组,告诉您每个点还剩下多少峰值。然后你就可以知道在O(1)时间间隔中是否有一个峰值。然后检查除数d需要O(n/d)时间。所有除数d上的n/d相加等于所有除数d上的d,结果是,根据相同的Wikipedia页面,O(n log n)。

票数 2
EN

Stack Overflow用户

发布于 2014-10-06 11:47:50

我用tmyklebu推荐的方式实现了一个解决方案(谢谢!)应该是n.log(log(n))。谦逊不再测试这个问题的“性能”(!)但python解决方案的准确率为100%。

顺便说一句,如果您一直在做Codility课程,那么您将从第8课:素数和复合数中记住,调和数运算的和将给O(log(n))复杂性。我们有一个简化的集合,因为我们只看因子分母。第9课:埃拉托斯提尼筛显示素数倒数之和是O(log(log(N),并声称“证明不是平凡的”。除数倒数和不同于素数倒数和,但我建议它也属于“非平凡”证明范畴!

代码语言:javascript
复制
def solution(data):

    length = len(data)

    # array ends can't be peaks, len < 3 must return 0    
    if len < 3:
        return 0

    peaks = [0] * length

    # compute a list of 'peaks to the left' in O(n) time
    for index in range(2, length):
        peaks[index] = peaks[index - 1]

        # check if there was a peak to the left, add it to the count
        if data[index - 1] > data[index - 2] and data[index - 1] > data[index]:
            peaks[index] += 1

    # candidate is the block size we're going to test
    for candidate in range(3, length + 1):

        # skip if not a factor
        if length % candidate != 0:
            continue

        # test at each point n / block
        valid = True
        index = candidate
        while index != length:

            # if no peak in this block, break
            if peaks[index] == peaks[index - candidate]:
                valid = False
                break

            index += candidate

        # one additional check since peaks[length] is outside of array    
        if index == length and peaks[index - 1] == peaks[index - candidate]:
            valid = False

        if valid:
            return length / candidate

    return 0
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26150180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档