[英]How do I use multiprocessing/multithreading to make my Python script quicker?
[英]Python how do i make list appends / extends quicker?
大家好。
试图在 python 上做得更好,并开始做 leetcode 问题。 我目前正在做一个,目标是捕获水。 链接 => https://leetcode.com/problems/trapping-rain-water/
问题是; 它让我花时间过长。 我的代码肯定效率低下。 在谷歌搜索之后,我发现.append 据说非常慢/效率低。 也是。扩展。
找不到任何使我的代码更快的明显方法; 因此我来到这里。
非常感谢任何回应
class Solution:
def trap(self, height: List[int]) -> int:
max_height = max(height)
water_blocks = 0
for element in range(max_height):
local_map = []
element = element + 1
for block in height:
if block >= element:
local_map.extend([1])
else:
local_map.extend([0])
if local_map.count(1) > 1:
first_index = local_map.index(1)
reversed_list = local_map[::-1]
last_index = len(local_map) - 1 - reversed_list.index(1)
water_count = last_index - first_index - 1 - (local_map.count(1) - 2)
water_blocks += water_count
else:
continue
return water_blocks
尽管可以避免许多count
和index
调用,但两个大的嵌套循环可能仍然是个问题。 对于外循环, max_height
可以是大数,内循环遍历整个列表。 您可能需要提出不同的算法。
我没有 leetcode 帐户,所以我无法真正测试我的代码,但这是我的建议:它只遍历height
-list 一次,并带有一个小的内部循环来查找下一个匹配的墙。
class Solution:
def trap(self, h):
water = 0
current_height = 0
for i, n in enumerate(h):
# found a "bucket", add water
if n < current_height:
water += current_height - n
else: # found a wall. calculate usable height
current_height = self.n_or_max(h[i+1:], n)
return water
def n_or_max(self, h, n):
local_max = 0
for i in h:
if i > local_max:
local_max = i
# that's high enough, return n
if i >= n:
return n
return local_max
这里有一些提示:
list.count()
或list.index()
(即尝试删除local_map.count(1)
、 local_map.index(1)
和reversed_list.index(1)
)。 第一个将(在内部)循环整个list
,如果list
很大,这显然很昂贵。 第二个将遍历列表,直到找到1
。 目前,您甚至有两次调用local_map.count(1)
将始终返回相同的答案,因此至少只需将结果存储在一个变量中。 在您对block
的循环中,您自己构造了local_map
,因此您实际上确实知道它包含的内容,之后您不必再搜索它。 只需将一些if
s 放入block
s 的第一个循环中。local_map[::-1]
不仅在整个list
上运行,而且还将整个内容复制到一个新list
(向后,但这并没有真正导致问题)。 同样,这个新列表不包含新信息,因此您无需执行此操作即可计算water_count
的值。element = element + 1
可以获得进一步的优化。 只需移动范围,如range(1, max_height + 1)
。list.append(x)
到list.extend([x])
。 它不是很大,但后者必须创建一个附加list
(长度为 1),将x
放入其中,循环遍历list
并将 append 其元素(仅x
)添加到大list
。 最后,长度为 1 的列表被丢弃。 相反, list.append(x)
只是将x
附加到list
,不需要临时的长度为 1 的list
。 请注意, list.append()
并不慢。 这是一个 function 调用,它总是有点慢,但实际的数据操作很快:恒定时间,甚至巧妙地摊销,正如 juanpa.arrivillaga 所写。
这是看待问题的另一种方式。 这会从左到右扫描垃圾箱,在每个点上,我都会跟踪每个级别有多少单位的水被拦住。 当有一堵高墙时,我们会统计它所筑坝的任何单位,并清除它们。 但是,这仍然会在最后一个测试的旁边获得一个“超时”标志,该测试有大约 10,000 个条目。 在我相对较旧的盒子上需要 20 秒。
class Solution():
def trap(self, height):
trapped = 0
accum = [0]*max(height)
lastwall = -1
for h in height:
# Take credit for everything up to our height.
trapped += sum(accum[0:h])
accum[0:h] = [0]*h
for v in range(h,lastwall):
accum[v] += 1
lastwall = max(lastwall,h)
return trapped
print(Solution().trap([0,1,0,2,1,0,1,3,2,1,2,1])) # 6
print(Solution().trap([4,2,0,3,2,5])) # 9
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.