繁体   English   中英

比较在 for 循环中设置列表和在 for 循环中设置 x 的时间复杂度

[英]Comparing time complexity for making list to set in a for loop and x in list in a for loop

我正在从CodilityGenomicRangeQuery练习。 (我不在这里粘贴问题,因为它有点太长了。)

这是我的答案,它已经通过了测试。 它表明检测到的时间复杂度为 O(N + M)。

def solution(S, P, Q):
    impacts_dic = {"A": 1, "C": 2, "G": 3, "T": 4}

    result = []
    for i in range(len(P)):
        if P[i] == Q[i]:
            result.append(impacts_dic[S[P[i]]])
            continue

        impact_list = S[P[i]:Q[i] + 1]

        if "A" in impact_list:
            result.append(impacts_dic["A"])
        elif "C" in impact_list:
            result.append(impacts_dic["C"])
        elif "G" in impact_list:
            result.append(impacts_dic["G"])
        else:
            result.append(impacts_dic["T"])

    return result

示例测试:

S = "CAGCCTA"

P = [2, 5, 0]
Q = [4, 5, 6]
print(solution(S, P, Q))

print(solution('A', [0], [0]))

但我不太明白为什么时间复杂度是O(N + M)

“for 循环”的时间复杂度为O(M) ,列表的“x in s”为O(len(impact_list)) ,其中 len(impact_list) <= N。但为什么时间复杂度不是O(N *米)

我也不明白如何计算我的第一个尝试答案的时间复杂度。 而不是impact_list = S[P[i]:Q[i] + 1]我写了impact_set = set(S[P[i]:Q[i] + 1]) ,时间复杂度是O(N * M ) 我认为这是因为使列表设置的时间复杂度为O(n) ,并且 n <= N。

比较这两个,为什么第一个是加M和N,而第二个是乘M和N?

检测到的时间不对,你的人工分析是对的。 两种解决方案都是 O(N * M)。

曲线的形状暂时不可见,因此某些自动化方法可能会出错,尤其是当 Python 操作可能具有截然不同的常数因子时。

我绘制了这个设置 N = M 的程序的输出:

import timeit


def solution(S, P, Q):
    impacts_dic = {"A": 1, "C": 2, "G": 3, "T": 4}

    result = []
    for i in range(len(P)):
        if P[i] == Q[i]:
            result.append(impacts_dic[S[P[i]]])
            continue

        impact_list = S[P[i]:Q[i] + 1]

        if "A" in impact_list:
            result.append(impacts_dic["A"])
        elif "C" in impact_list:
            result.append(impacts_dic["C"])
        elif "G" in impact_list:
            result.append(impacts_dic["G"])
        else:
            result.append(impacts_dic["T"])

    return result


def measure(n, m):
    return timeit.timeit(lambda: solution("C" * n, [0] * m, [n - 1] * m), number=3)


for n in range(1, 100002, 1000):
    print(f"{n}\t{measure(n, n):f}")

正如您所看到的,它是一条抛物线,而不是您期望的 O(N + M) 直线:

时间与输入大小的关系图

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM