我正在解决一个问题,我要创建一个堆栈,在该堆栈上实现一系列以字符串数组形式给出的operations
(3个变体:push x
,{{1} },pop
)并在每次操作后打印出堆栈顶部(如果堆栈为空,则打印出inc y x
)。 EMPTY
和Push
将按预期运行,并且pop
将堆栈中底部的inc
元素增加y
。似乎很简单。
其他约束如下:
这是我写的解决方案:
x
我的函数通过了10/14个测试用例,但最后四个是def superStack(operations):
# create stack
stack = []
add = stack.append
# loop through operations
for x in range(operations_cnt):
start = operations[x].startswith
# if push command, append number to stack and print top of stack
if start("push"):
add(int(operations[x].split()[1]))
print(stack[-1])
# elif pop command, remove last number appended and print new top of stack or EMPTY if empty
elif start("pop"):
stack.pop()
if not stack:
print("EMPTY")
else:
print(stack[-1])
# elif inc command, increase bottom numbers accordingly and print top of stack
elif start("inc"):
params = operations[x].split()
n = int(params[1])
m = int(params[2])
for y in range(n):
stack[y] += m
print(stack[-1])
。不幸的是,我只获得了前三个测试用例的输入和输出,所以我对到底出了什么问题不知所措。
如何优化此功能以避免超时?
答案 0 :(得分:1)
将冗余计算移到循环外。这些步骤需要花费一些时间,这些超时会加到用于超时的任何限制中。
例如,没有理由在int(operations[x].split()[1]
循环内重新计算for
。
您只需要split
一次,并且只需将每个拆分元素转换为int
一次。
答案 1 :(得分:0)
您可能想看看numpy
。
我在这里实现inc
函数:
import time
size=10**8
half=int(size/2)
stack = [1]*size
start_time = time.time()
for y in range(0,half):
stack[y] += 2
print("--- %s seconds ---" % (time.time() - start_time))
import numpy as np
stack = np.asarray([1]*size)
start_time = time.time()
stack[0:half] += 2
print("--- %s seconds ---" % (time.time() - start_time))
这个,把这个输出游戏给我:
$ python3 myprog.py
--- 5.146971225738525 seconds ---
--- 0.49752235412597656 seconds ---
请注意,我绝不是numpy的专家,经验丰富的用户可能会有更好的书写方式。我的主要观点是,对于长列表和矩阵的操作,numpy比本地python快得多。
(从https://stackoverflow.com/a/1557584/6699433复制的时间度量)
这是一个完整的类,您基本上只需很少的工作就可以将其插入代码中:
import numpy as np
class Stack:
def __init__(self):
self.stack = np.arange(0)
def pop(self):
self.stack.resize(len(self.stack)-1)
def push(self, x):
self.stack.resize(len(self.stack)+1)
self.stack[-1]=x
def inc(self, y, x):
self.stack[0:y] += x
def printTop(self):
if(len(self.stack) == 0):
print("EMPTY")
else:
print(self.stack[-1])
它看起来像这样:
def superStack(operations):
stack = Stack()
for x in range(0,operations_cnt):
if operations[x].startswith("push"):
stack.push(int(operations[x].split()[1]))
elif operations[x].startswith("pop"):
stack.pop()
elif operations[x].startswith("inc"):
stack.inc(int(operations[x].split()[1]), int(operations[x].split()[2]))
stack.printTop()
答案 2 :(得分:0)
可能会加快处理速度的一件事是利用以下事实:操作数量少于200000。由于扩展堆栈的唯一操作是推入,并且始终仅添加一个元素,因此堆栈永远不需要更大比这个值。请注意,这个想法也可以与我涉及numpy
的答案一起使用。
我还更改了inc
以利用列表理解。有点快。
class Stack:
def __init__(self):
self.stack = [0]*200000
self.size = 0
def push(self, x):
self.stack[self.size]=x
self.size+=1
def pop(self):
self.size-=1
def inc(self, y, x):
self.stack[0:y] = [e+x for e in self.stack[0:y]]
def printTop(self):
if(self.size == 0):
print("EMPTY")
else:
print(self.stack[self.size-1])