这是我目前的解决方案。它比柯克·斯特劳泽的解决方案快了大约60%。在def shift(self, sequence, right=False):
if right:
sequence = sequence[::-1]
values = []
empty = 0
for n in sequence:
if values and n == values[-1]:
values[-1] = 2*n
empty += 1
elif n:
values.append(n)
else:
empty += 1
values += [0]*empty
if right:
values = values[::-1]
return values
我更有效的方法是:
^{pr2}$
柯克的解决方案:def streaming_sum(sequence):
values = reversed(sequence)
last = next(values)
for value in values:
if value == last:
yield last + value
last = 0
else:
yield last
last = value
yield last
def shift2(sequence):
length = len(sequence)
reduced = list(reversed(list(filter(None, streaming_sum(sequence)))))
return [0] * (length - len(reduced)) + reduced
我对柯克函数的改进(40%加速):def shift3(sequence):
length = len(sequence)
reduced = [n for n in filter(None, streaming_sum(sequence))][::-1]
return [0] * (length - len(reduced)) + reduced
时间安排:from timeit import Timer
tests = [[1000, 1000, 1000, 1000],
[1000, 0, 0, 1000],
[0, 1000],
[1000, 1000, 0, 500, 0, 500, 1000, 0, 0, 100, 100, 100]]
t1, t2, t3 = 0, 0, 0
for test in tests:
t1 += Timer(lambda: shift(test)).timeit()
t2 += Timer(lambda: shift2(test)).timeit()
t3 += Timer(lambda: shift3(test)).timeit()
>>> print(t1, t2, t3)
10.706327316242147 26.92895738572211 16.65189852514444
我的一对我的效率更高的一个对我的效率更高的一个没有选择右对齐而不是左对齐的时间:10.502816527107633 8.503653343656246 8.15101370397509