我正在尝试优化在竞争性编程网站上超时的解决方案。我开始使用 cProfile,它似乎显示bisect_right()
需要 4 倍于insort_right()
. 这是在输入列表上运行的分析,包含超过 40k 个条目:
89936 function calls in 3.596 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 3.596 3.596 <string>:1(<module>)
1 0.180 0.180 3.596 3.596 leetcode.py:38(go)
1 3.357 3.357 3.415 3.415 leetcode.py:6(numSubarrayProductLessThanK)
44965 0.045 0.000 0.045 0.000 {built-in method _bisect.bisect_right}
44965 0.014 0.000 0.014 0.000 {built-in method _bisect.insort_right}
1 0.000 0.000 3.596 3.596 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {built-in method builtins.print}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
我认为所有列表插入都是 O(n),因为平均必须移动 n/2 个元素。简单地确定插入排序列表的位置将是 O(log n)。但在配置文件报告中,它看起来颠倒了:插入器insort_right()
比位置确定器慢bisect_right()
。我哪里错了?这是代码:
from bisect import insort, bisect
class Solution:
def numSubarrayProductLessThanK(self, nums, k):
if k == 0:
return 0
result = 0
product = 1
products = [1]
products_n = 1
for num in nums:
product *= num
factor_min = product // k
n_factors_less = products_n - bisect(products, factor_min)
result += n_factors_less
insort(products, product)
products_n += 1
return result
谢谢你的关注。